سون سگمنت (Seven-segment) یک قطعه برای نمایش ارقام و بعضی حروف خاص هست. حتما سون سگمنت ها رو تو آسانسور یا محافظ کولر (اونایی که ولت سنج دارن) یا روی بعضی کولر ها برای نمایش دما دیدید. این قطعه دارای هفت LED اصلی برای نمایش ارقام و ... و یک LED اختیاری برای نقطه هست که در واقع برای کامل شدن یک بایت (8 بیت) اضافه می شود. از آن جا که این قطعه از LED ها تشکیل شده دارای دو نوع کاتد مشترک (com-cathode) و آند مشترک (com-anode) که در آن ها به ترتیب پایه های منفی آن ها یا مثبت آن ها به هم وصل شده اند. البته که این تفاوت در ظاهر و کارکرد فرقی نخواهد داشت اما در زمان برنامه نویسی تفاوت هایی هست.

همانطور که می بینید بخش های اصلی یک سون سگمنت با حروف A تا G نام گذاری شده اند و نقطه که اختیاری است با حرف DP که مخفف Decimal point است نام گذاری می شود.

این جدول یک جدول عمومی برای تمام انواع سون سگمنت ها (کاتد یا آند مشترک) است. با استفاده از این جدول می توانیم به کد های برای نمایش هر کاراکتر برسیم. از آنجا که برای زخیره این کد ها از آرایه استفاده می کنیم شماره ردیف را از صفر شروع کردم تا راحت تر باشیم. شما می توانید علائم و هر کاراکتری که نیاز داشتید را با استفاده از شکل بالا به جدول اضافه کنید. مثل علامت درجه (°) که کد آن ABFG می باشد. معمولا در این جدول ها مستقیما کد های باینری یا هکس را هم می نویسند با فرض این که پایه ها به ترتیب مثل ABCDEFG-DP چیده شده باشند، ولی در بازار چنین سون سگمنت هایی کم پیدا میشند، از طرفی بسته به شرایط در هنگام طراحی مدار این ترتیب ممکن است به هم بریزد. در کد من از یک ترفند ساده برای رفع پیچیدگی ها و ساده تر شدن تنظیم پایه ها و نوع سون سگمنت استفاده شده.

کد

ابتدا در بالای کد خطوط زیر را بنویسید:

#define F_CPU 1000000
#include <avr/io.h>
#include <util/delay.h>

این ها باید جز خطوط اولیه کد برنامه باشند، خط اول فرکانس کاری پیشفرض CPU برای میکروی ATmega8 رو مشخص می کنه که برای ایجاد وقفه به آن نیاز داریم.

سپس با استفاده از #define محل اتصال پایه به میکر رو مشخص می کنیم. برای سادگی کار تمام پایه ها به یک پورت (PORTD) وصل شده اند و از آنجا که مدل خاصی مد نظر نیست همه ی پایه ها به ترتیب هستند.

#define A (1<<PIND0)
#define B (1<<PIND1)
#define C (1<<PIND2)
#define D (1<<PIND3)
#define E (1<<PIND4)
#define F (1<<PIND5)
#define G (1<<PIND6)
#define DP (1<<PIND7)

حال که پایه ها را داریم می توانیم تمام اعداد/حروف را در یک آرایه ذخیره کنیم (بسیاری از این کاراکتر ها اختیاری است ولی چون این صرفا یک پروژه آزمایشیست همه را نمایش می دهیم):

char segCodes[] = {
    A|B|C|D|E|F,    //0
    B|C,            //1
    A|B|D|E|G,      //2
    A|B|C|D|G,      //3
    B|C|F|G,        //4
    A|C|D|F|G,      //5
    A|C|D|E|F|G,    //6
    A|B|C|F,        //7
    A|B|C|D|E|F|G,  //8
    A|B|C|D|F|G,    //9
    A|B|C|E|F|G,    //A
    C|D|E|F|G,      //b
    A|D|E|F,        //C  D|E|G,          //c
    B|C|D|E|G,      //d
    A|D|E|F|G,      //E
    A|E|F|G,        //F
    A|C|D|E|F,      //G
    B|C|E|F|G,      //H  C|E|F|G,        //h  
    B|C|D|E,        //J
    D|E|F,          //L
    C|D|E|G,        //o
    A|B|E|F|G,      //P
    A|B|C|F|G,      //q
    E|G,            //r
    D|E|F|G,        //t
    B|C|D|E|F,      //U  C|D|E,          //u
    B|C|D|F|G,      //y
};

حال نکته اساسی اینجاست که در سون سگمنت های کاتد مشترک پایه منفی تمام LED ها به هم وصل هستند و پایه های مثبت به (ورودی های) A, B, C, ... , G, DP متصل است و در آند مشترک ها پایه ی مثبت تمام LED ها به هم متصل هستند و پایه های منفی آن ها به (خروجی های) A, B, C, ... ,G, DP متصل هستند. این به این معنی است که در آند مشترک ها برای روشن کردن هر LED باید به پایه ها پتانسیل مثبت (VCC یا همون سر مثبت باتری) و برای روشن کردن LED ها در نوع کاتد مشترک باید پتانسیل صفر یا منفی (GND یا VCC- یا همون سر منفی باتری) رو وصل کنیم.

در میکرو ها زمانی که یک پایه را 1 می کنیم که به آن High می گوییم پتانسیل آن برابر با VCC (پتانسیل مثبت خود میکرو، مثلا اگر با 5V میکرو را تغذیه می کنیم همون 5V) می شود و زمانی که پایه را صفر می کنیم که به آن Low می گوییم پتانسیل آن صفر می شود. این یعنی اگر برای نمایش عدد 8 در نوع کاتد مشترک زمانی که پایه کاتد به GND وصل است از کد 0x7f = 0b01111111 = A|B|C|D|E|F|G استفاده کنیم، برای نمایش آن در نوع آند مشترک زمانی که پایه آند به VCC وصل است باید از کد 0x80 = 0b10000000 = ~(A|B|C|D|E|F|G) استفاده کنیم.

 

⚠ هشدار: هرگز از سون سگمنت را بدون بستن مقاومت مناسب به پایه ها (... ,A, B) استفاده نکنید. فعلا در بخش توضیح کد هستیم و کاری با تعیین نوع مقاومت نداریم و دلیل آن نداریم!

 

برای نمایش همه کاراکتر ها با سون سگمنت آند مشترک این کد را برای تابع main بنویسید:

int main (void){
    DDRD=0xff;
    while(1)
        for(int i=0;i<27;i++){
            PORTD = segCodes[i];
            _delay_ms(500);
        }
}

و برای نمایش همه کاراکتر ها با سون سگمنت کاتد مشترک خط PORTD = segCodes[i] را با PORTD = ~segCodes[i] جایگزین کنید.

شبیه سازی در proteus و مدار

برنامه proteus را اجرا کنید و یک پروژه جدید بسازید، در بالای لیست Devices با انتخاب دکمه P قطعات لازم را بردارید، در این پروژه به قطعات زیر نیاز داریم:

  • ATmega8 (میکروی مورد نظر ما)
  • 7seg-digital (سون سگمنت از نوع آند مشترک)
  • res (مقاومت)

مقاومت پیشنهادی همون 390 اهم هست که برای 5v مناسب هست، این مقاومت رو قبل تر تو پروژه چشمک زن هشتایی هم استفاده کردیم، البته که همونطور که قبل تر گفتم بستن مقاومت در شبیه سازی الزامی نیست. اما تو مدل واقعی لازم هست، دلیلش رو هم قبلا گفتم؛ از اونجا که سون سگمنت از LED ساخته شده پس استفاده از اون بدون مقاومت می تونه باعث سوختن سون سگمنت و میکرو بشه.

می تونید فایل زیپ کل پروژه (کد + شبیه سازی) رو دانلود کنید: