راه اندازی سون سگمنت با AVR

توسط | 15 آذر, 1398 | AVR, میکروکنترلر, وبلاگ | 28 دیدگاه ها

راه-اندازی-سون-سگمنت-avr

آموزش AVR یوبرد

شاهکار 8بیتی اتمل

آموزش های رایگان AVR

فیلم های آموزش AVR

آموزش خصوصی AVR

اخبار جدید یوبرد در اینستاگرام

راه اندازی سون سگمنت با AVR مانند راه اندازی آن با میکروکنترلرهای دیگر معمولاً نیاز به کار با پورت های IO دارد. در راه اندازی سون سگمنت با پورت های IO، لازم است پایه های آن پورت ها خروجی و به شیوه ای مشخص مقدار دهی شوند. بنابراین عدد یا حرفی مشخص روی سون سگمنت نمایش داده می شود. روش های مختلفی برای مقدار دهی به پورت های IO و در نتیجه راه اندازی سون سگمنت وجود دارد.

ما در این نوشته به بیان یک روش راه اندازی پورت های IO در AVR برای کار با سون سگمنت 4 تایی می پردازیم. برای درک بهتر این شیوۀ راه اندازی، لازم است با پورت های IO در میکروکنترلرهای AVR آشنایی داشته باشیم. همان طور که خواهیم دید برای راه اندازی سون سگمنت از تابعی به نام SegmentPuts استفاده می کنیم. در این تابع با استفاده از تعدادی ماکرو به رجیسترهای پورت IO مقدار می دهیم. یکی از دلایل استفاده از این ماکروها این است که در توابع برنامه از مقدار دهی مستقیم به رجیسترها پرهیز کنیم.

برنامۀ راه اندازی سون سگمنت با AVR در این نوشته در نرم افزار اتمل استودیو نوشته شده است. در این نوشته برنامه را طوری می نویسیم که در کدویژن نیز قابل استفاده باشد. البته این برنامه صرفاً برای راه اندازی سون سگمنت است و فقط جنبۀ آموزشی دارد. فایل های شبیه سازی در نرم افزار پروتئوس و فایل های برنامه در اتمل استودیو و کدویژن در پیوست قرار دارند. در ادامه ابتدا روش مقدار دهی به رجیسترهای پورت IO را با استفاده از چند ماکرو توضیح می دهیم. سپس راه اندازی سون سگمنت یک رقمی را شرح و در نهایت به راه اندازی سون سگمنت 4 رقمی می پردازیم.

راه اندازی سون سگمنت با آردوینو

فیلم آموزش آردوینو مقدماتی

چند-سون-سگمنت

تصویر 1 – چند نمونه سون سگمنت

 

در ادامه ویدئویی مربوط راه اندازی سون سگمنت با AVR  ارائه شده است. که ویدئویی مربوط به آموزش های سالهای گذشته است. دیدن آن خالی از لطف نیست.

ویدئوی 1 – راه اندازی سون سگمنت با AVR

مقدار دهی به رجیسترهای پورت IO با ماکرو

در راه اندازی سون سگمنت با AVR با چند ماکرو به رجیسترهای پورت IO در AVR مقدار می دهیم. توجه داشته باشید که در اتمل استودیو نمی توانیم به طور مثال برای یک کردن پایۀ صفرم پورت A بنویسیم: PORTA.0=1. مقدار دهی به رجیسترهای AVR به این روش تنها در کدویژن میسر است. بنابراین با استفاده از ماکروهایی که خواهیم دید، به رجیسترهای پورت IO مقدار می دهیم. این ماکروها هم در اتمل استودیو و هم در کدویژن قابل استفاده اند. به مثال زیر توجه کنید:

#define SegmentDig3DdrNum       DDRA
#define SegmentDig3PortNum      PORTA
#define SegmentDig3Bit          0
#define SegmentDig3Ddr(x)  ((x) ? (SegmentDig3DdrNum |= (1 << SegmentDig3Bit) ) :(SegmentDig3DdrNum&= (~(1 << SegmentDig3Bit)) ));
#define SegmentDig3Port(x) ((x) ? (SegmentDig3PortNum |= (1 << SegmentDig3Bit) ) : (SegmentDig3PortNum&= (~(1 << SegmentDig3Bit)) ));

با استفاده از SegmentDig3Ddr(x) می توانیم پایۀ مشترک رقم سوم (دهگان) سون سگمنت را ورودی یا خروجی کنیم. با استفاده از SegmentDig3Port(x) نیز می توانیم آن را صفر یا یک کنیم. کافی است به جای x صفر یا 1 قرار دهیم. سه سطر اول نیز دیفاین هایی برای استفاده در دو دیفاین آخر است. و در آنها پایۀ مشترک رقم سوم سون سگمنت را روی پایۀ PA0 قرار داده ایم. در دو دیفاین آخر ماکروها به این صورت هستند:

(x) ? (SegmentDig3DdrNum |= (1 << SegmentDig3Bit) ) :      (SegmentDig3DdrNum&= (~(1 << SegmentDig3Bit)))
(x) ? (SegmentDig3PortNum |= (1 << SegmentDig3Bit) ) :      (SegmentDig3PortNum&= (~(1 << SegmentDig3Bit)))

 

که در اولی اگر x برابر 1 باشد، دستور SegmentDig3DdrNum |= (1 << SegmentDig3Bit) اجرا می شود. این دستور با توجه به دیفاین های سه سطر اول معادل است با:

DDRA|=(1<<0)

 

اگر x صفر باشد، دستور SegmentDig3DdrNum&= (~(1 << SegmentDig3Bit)) اجرا می شود. که معادل است با:

 

DDRA&=~(1<<0)

 

که با این دو دستور مقدار بیت صفرم رجیستر DDRA بدون تغییر بیت های دیگر، یک و صفر می شود. مقدار بیت صفرم رجیستر PORTA نیز به همین روش تغییر می کند. روش استفاده از این دیفاین ها به صورت زیر است. در سطر اول PA0 را خروجی کرده ایم و در سطر دوم به آن مقدار صفر داده ایم.

SegmentDig3Ddr (1);
SegmentDig3Port (0);

راه-اندازی-یک-رقم

تصویر 2 – نمایش عدد 8 در رقم صدگان سون سگمنت آند مشترک با صفر کردن پایه های a تا g و یک کردن پایۀ مشترک

برای بررسی دیفاین های مربوط به پایه های دیگر، فایل های برنامه را که در پیوست قرار دارد، مشاهده نمایید.

نمایش اعداد روی سون سگمنت

برای راه اندازی سون سگمنت با AVR یا هر میکروکنترلر دیگر ابتدا باید روش نمایش روی یک رقم از سون سگمنت را بیاموزیم. برای نمایش اعداد صفر تا 9 و برخی حروف روی سون سگمنت لازم است که برخی سگمنت ها روشن و برخی خاموش باشند. در سون سگمنت های آند مشترک لازم است پایۀ مشترک که آند است به VCC متصل شود. بنابراین برای روشن کردن هر سگمنت، باید پایۀ مربوط را صفر کرد. در سون سگمنت های کاتد مشترک، پایۀ مشترک به زمین وصل می شود. برای روشن کردن هر سگمنت باید به پایۀ مربوط مقدار 1 داد. در جدول 1 وضعیت پایه های هر سگمنت برای نمایش اعداد صفر تا 9 مشخص شده است.

مدار-داخلی-سون-سگمنت

تصویر 3 – مدار داخلی سون سگمنت آند مشترک(سمت راست) و کاتد مشترک (سمت چپ)

Common Cathode Common Anode
a b c d e f g a b c d e f g
0 1 1 1 1 1 1 0 0 0 0 0 0 0 1
1 0 1 1 0 0 0 0 1 0 0 1 1 1 1
2 1 1 0 1 1 0 1 0 0 1 0 0 1 0
3 1 1 1 1 0 0 1 0 0 0 0 1 1 0
4 0 1 1 0 0 1 1 1 0 0 1 1 0 0
5 1 0 1 1 0 1 1 0 1 0 0 1 0 0
6 1 0 1 1 1 1 1 0 1 0 0 0 0 0
7 1 1 1 0 0 0 0 0 0 0 1 1 1 1
8 1 1 1 1 1 1 1 0 0 0 0 0 0 0
9 1 1 1 1 0 1 1 0 0 0 0 1 0 0

جدول 1 – وضعیت پایه های سون سگمنت برای نمایش اعداد صفر تا 9

استفاده از ماکروها برای نمایش اعداد در سون سگمنت

برای نمایش اعداد روی سون سگمنت باید مطابق جدول بالا به پایه های a تا g سون سگمنت مقدار بدهیم. مثلاً برای نمایش عدد 1 در سون سگمنت های آند مشترک، لازم است پایه های b و c صفر و پایه های دیگر سگمنت ها 1 باشد. در این صورت اگر آند (پایۀ مشترک) این سون سگمنت به VCC متصل شده باشد، عدد 1 نمایش داده می شود. برای راه اندازی سون سگمنت با AVR، کافی است از دیفاین هایی که نوشتیم استفاده کنیم. مثلاً برای نمایش عدد 1 در رقم هزارگان (رقم اول) سون سگمنت 4 تایی آند مشترک، باید مطابق دستورهای زیر عمل کنیم.

ابتدا پایه های مورد نظر را خروجی می کنیم. سپس همان طور که گفتیم باید پایۀ مشترک این رقم از سون سگمنت به VCC متصل شود. ما به جای اتصال به VCC، به آن مقدار 1 می دهیم. با صفر کردن پایۀ سگمنت های b و c و یک کردن پایۀ دیگر سگمنت ها، عدد 1 روی رقم مورد نظر نمایش داده می شود. در کدهای زیر OutPut و Set و Clear در ابتدای برنامه دیفاین شده اند.

SegmentDig1Ddr (OutPut);
SegmentADdr (OutPut);
SegmentBDdr (OutPut);
SegmentCDdr (OutPut);
SegmentDDdr (OutPut);
SegmentEDdr (OutPut);
SegmentFDdr (OutPut);
SegmentGDdr (OutPut);
SegmentDig1Port (Set);
SegmentAPort (Set);
SegmentBPort (Clear);
SegmentCPort (Clear);
SegmentDPort (Set);
SegmentEPort (Set);
SegmentFPort (Set);
SegmentGPort (Set);

 

نمایش-عدد-سون-سگمنت

تصویر 4 – نمایش عدد 1 در رقم هزارگان سون سگمنت

نوشتن تابع برای راه اندازی سون سگمنت با AVR

در ابتدا باید تابعی بنویسیم که عددی را در ورودی بگیرد و با استفاده از ماکروهای پیشین، به پایه های هر سگمنت مقدار بدهد. می توان یک ورودی دیگر برای تعیین رقم مورد نظر تعریف کرد. بنابراین تابعی به صورت زیر خواهیم داشت. چهار شرط اول برای بررسی مقدار Digit است. این متغیر که ورودی تابع است مقادیر 1 تا 4 را می پذیرد. اگر مقدارش 1 باشد، عدد نمایش داده شده در سون سگمنتِ 4 تایی، روی رقم هزارگان خواهد بود. اگر مقدارش 2 باشد، عدد روی رقم صدگان نمایش داده می شود. برای مقادیر 3 و 4 نیز به ترتیب، عدد روی ارقام دهگان و یکان نمایش داده می شود.

در ده شرط بعدی، متغیر Number که ورودی تابع است، مورد بررسی قرار می گیرد. این متغیر می تواند اعداد صفر تا 9 باشد و برای هر کدام از این مقادیر یک شرط تعریف شده است. اگر Number برابر صفر باشد، دستورات شرط اول اجرا می شود، که در آن پایۀ همۀ سگمنت ها به غیر از سگمنت g، صفر می شود. در این صورت عدد صفر روی سون سگمنت نمایش داده می شود. برای شرط های دوم تا دهم نیز به همین شکل اعداد 1 تا 9 نمایش داده می شوند. دستورات درون این شرط ها مطابق جدول 1 برای نمایش روی سون سگمنت آند مشترک هستند. این تابع به شکلی دیگر برای راه اندازی سون سگمنت با STM32 به کار گرفته شده است. برای اطلاعات بیشتر به نوشتۀ «راه اندازی سون سگمنت با STM32، رجیستری و HAL» مراجعه نمایید.

void SegmentPutsDigit (char Number , char Digit)
{
if (Digit == 1)

{

SegmentDig1Port (Set);

SegmentDig2Port (Clear);

SegmentDig3Port (Clear);

SegmentDig4Port (Clear);

}
else if (Digit == 2)

{

SegmentDig1Port (Clear);

SegmentDig2Port (Set);

SegmentDig3Port (Clear);

SegmentDig4Port (Clear);

}
else if (Digit == 3)

{

SegmentDig1Port (Clear);

SegmentDig2Port (Clear);

SegmentDig3Port (Set);

SegmentDig4Port (Clear);

}
else if (Digit == 4)

{

SegmentDig1Port (Clear);

SegmentDig2Port (Clear);

SegmentDig3Port (Clear);

SegmentDig4Port (Set);

}

if (Number == 0)

{

SegmentAPort (Clear);

SegmentBPort (Clear);

SegmentCPort (Clear);

SegmentDPort (Clear);

SegmentEPort (Clear);

SegmentFPort (Clear);

SegmentGPort (Set);

SegmentDpPort (Set);

}
else if (Number == 1)

{

SegmentAPort (Set);

SegmentBPort (Clear);

SegmentCPort (Clear);

SegmentDPort (Set);

SegmentEPort (Set);

SegmentFPort (Set);

SegmentGPort (Set);

SegmentDpPort (Set);

}
else if (Number == 2)

{

SegmentAPort (Clear);

SegmentBPort (Clear);

SegmentCPort (Set);

SegmentDPort (Clear);

SegmentEPort (Clear);

SegmentFPort (Set);

SegmentGPort (Clear);

SegmentDpPort (Set);

}
else if (Number == 3)

{

SegmentAPort (Clear);

SegmentBPort (Clear);

SegmentCPort (Clear);

SegmentDPort (Clear);

SegmentEPort (Set);

SegmentFPort (Set);

SegmentGPort (Clear);

SegmentDpPort (Set);

}
else if (Number == 4)

{

SegmentAPort (Set);

SegmentBPort (Clear);

SegmentCPort (Clear);

SegmentDPort (Set);

SegmentEPort (Set);

SegmentFPort (Clear);

SegmentGPort (Clear);

SegmentDpPort (Set);

}
else if (Number == 5)

{

SegmentAPort (Clear);

SegmentBPort (Set);

SegmentCPort (Clear);

SegmentDPort (Clear);

SegmentEPort (Set);

SegmentFPort (Clear);

SegmentGPort (Clear);

SegmentDpPort (Set);

}
else if (Number == 6)

{

SegmentAPort (Clear);

SegmentBPort (Set);

SegmentCPort (Clear);

SegmentDPort (Clear);

SegmentEPort (Clear);

SegmentFPort (Clear);

SegmentGPort (Clear);

SegmentDpPort (Set);

}
else if (Number == 7)

{

SegmentAPort (Clear);

SegmentBPort (Clear);

SegmentCPort (Clear);

SegmentDPort (Set);

SegmentEPort (Set);

SegmentFPort (Set);

SegmentGPort (Set);

SegmentDpPort (Set);

}
else if (Number == 8)

{

SegmentAPort (Clear);

SegmentBPort (Clear);

SegmentCPort (Clear);

SegmentDPort (Clear);

SegmentEPort (Clear);

SegmentFPort (Clear);

SegmentGPort (Clear);

SegmentDpPort (Set);

}
else if (Number == 9)

{

SegmentAPort (Clear);

SegmentBPort (Clear);

SegmentCPort (Clear);

SegmentDPort (Clear);

SegmentEPort (Set);

SegmentFPort (Clear);

SegmentGPort (Clear);

SegmentDpPort (Set);

}

}

نمایش-چهار-رقم-سون-سگمنت

تصویر 5 – عملکرد چهار شرط ابتدای تابع و تغییر متغیر Digit در نمایش عدد 1

راه اندازی سون سگمنت 4 تایی با تابع

برای نمایش عدد چهار رقمی باید در هر لحظه تنها یکی از ارقام فعال باشد. در همین لحظه باید عدد مربوط به آن رقم، روی سون سگمنت قرار بگیرد. چرا که پایه های مربوط به سگمنت های a تا g بین هر چهار رقم سون سگمنت 4 تایی، مشترک است. راه اندازی سون سگمنت با AVR یا هر میکروکنترلر یا المان دیگر به این صورت است که پایۀ مشترک (آند یا کاتد) یک رقم برای نمایش، مقدار دهی می شود. در همین لحظه عدد مربوط به آن رقم، با مقدار دهی به پایه های a تا g، روی سون سگمنت نمایش داده می شود. در این لحظه باید ارقام دیگر خاموش باشند.

در لحظۀ بعد باید رقم بعدی فعال شود و پایه های a تا g طوری مقدار بگیرند که عدد مربوط به آن رقم، نمایش داده شود. بنابراین با نمایش عدد مربوط به هر رقم در یک لحظه، عدد چهار رقمی نمایش داده می شود. آنچه که مهم است، زمانی است که هر رقم عددی را نمایش می دهد. اگر بخواهیم سون سگمنت با فرکانس مثلاً 60 هرتز رفرش شود، باید مدت زمانی که هر رقم عددی را نمایش می دهد برابر حدوداً 4 میلی ثانیه باشد. در این صورت 16 میلی ثانیه طول می کشد که سون سگمنت رفرش شود. که این رفرش شدن با فرکانس 62.5 هرتز خواهد بود.

به تابع زیر دقت کنید. ابتدا ارقام عدد ورودی تفکیک می شوند. سپس با تأخیرهای 4 میلی ثانیه در تابع SegmentPutsDigit قرار می گیرند. Hezargan و Sadgan و Dahgan و Yekan در ابتدای برنامه دیفاین شده اند. استفاده از این تابع مشکلاتی به همراه دارد. در ادامه آنها را توضیح می دهیم و روشی برای رفع آن بیان می کنیم.

void SegmentPutsNumber(unsigned int Number)
{
unsigned char Dig1Num=0,  Dig2Num=0, Dig3Num=0, Dig4Num=0;
Dig4Num=Number%10;
Dig3Num=(Number/10)%10;
Dig2Num=(Number/100)%10;
Dig1Num= Number/1000;
SegmentPutsDigit (Dig1Num,Hezargan);
_delay_ms(4);
SegmentPutsDigit (Dig2Num,Sadgan);
_delay_ms(4);
SegmentPutsDigit (Dig3Num,Dahgan);
_delay_ms(4);
SegmentPutsDigit (Dig4Num,Yekan);
_delay_ms(4);
}

و

نمایش-عدد-چهار-مرحله

تصویر 6 – نمایش عدد 1234 روی ارقام سون سگمنت در چهار مرحله

شرح برنامۀ راه اندازی سون سگمنت با AVR

پس از نوشتن دیفاین ها و توابع راه اندازی سون سگمنت، باید آنها را در تابع main به کار ببریم. ابتدا لازم است که پایه های پورت IO که به سون سگمنت متصل هستند، خروجی شوند. این کار با استفاده از ماکروهایی که تعریف کردیم امکان پذیر است. تابع main به صورت زیر خواهد بود. ابتدا پایه های میکروکنترلر که به پایه های مشترک (آندها) ارقام سون سگمنت متصل است، خروجی می شوند. پس از آن پایه های a تا g نیز خروجی می شوند. در ادامه پایه های مشترک یک می شوند و پس از آن پایه های a تا g صفر می شوند. در این صورت در لحظۀ اول عدد 8888 به مدت 1 ثانیه نمایش داده می شود.

در حلقۀ while تابع SegmentPutsNumber نوشته شده که می توانیم در ورودی آن عدد صفر تا 9999 را قرار دهیم. ایرادی که این برنامه دارد، تابع SegmentPutsNumber است. در این تابع چهار تأخیر 4 میلی ثانیه ای وجود دارد. برای نمایش یک عدد چند رقمی روی سون سگمنت، لازم است این تابع دائماً اجرا شود. و اگر دستورات دیگری در حلقۀ while داشته باشیم با دورۀ زمانی 16 میلی ثانیه اجرا خواهند شد. همچنین اگر دستورات درون while زمانبر باشند، دیگر عدد چند رقمی روی سون سگمنت نمایش داده نخواهد شد و چشمک زدن سون سگمنت قابل مشاهده خواهد بود. در ادامه روشی را برای رفع این مشکل بیان می کنیم.

int main(void)
{
SegmentDig1Ddr (OutPut);
SegmentDig2Ddr (OutPut);
SegmentDig3Ddr (OutPut);
SegmentDig4Ddr (OutPut);
SegmentADdr (OutPut);
SegmentBDdr (OutPut);
SegmentCDdr (OutPut);
SegmentDDdr (OutPut);
SegmentEDdr (OutPut);
SegmentFDdr (OutPut);
SegmentGDdr (OutPut);
SegmentDig1Port (Set);
SegmentDig2Port (Set);
SegmentDig3Port (Set);
SegmentDig4Port (Set);
SegmentAPort (Clear);
SegmentBPort (Clear);
SegmentCPort (Clear);
SegmentDPort (Clear);
SegmentEPort (Clear);
SegmentFPort (Clear);
SegmentGPort (Clear);
_delay_ms(1000);
while (1)
{
SegmentPutsNumber(5678);
}
}

نکته: در نرم افزار پروتئوس با تأخیر 4 میلی ثانیه عدد به صورت کامل روی سون سگمنت نمایش داده نمی شود. اما در عمل برنامه به طور صحیح کار می کند (تصویر 8). برای نمایش عدد روی سون سگمنت در پروتئوس باید تأخیرها در تابع SegmentPutsNumber زیاد شوند. که در این صورت هر رقم با تأخیر نمایش داده می شود.

عدم-نمایش-کامل-سون-سگمنت

تصویر 7 – عدم نمایش کامل عدد چهار رقمی

حذف delay از برنامه و رفع چشمک زدن سون سگمنت

همان طور که از متن تابع SegmentPutsNumber مشخص است، اگر این تابع دائماً اجرا نشود، عددی چند رقمی در سون سگمنت نمایش داده نمی شود. این تابع باید در حلقۀ while برنامه به تنهایی اجرا شود تا بتواند عددی چند رقمی را به طور پیوسته نمایش دهد. بنابراین نمی توانیم بگوییم راه اندازی سون سگمنت با AVR به طور کامل انجام شده است. از جمله راه هایی که می توان این مشکل را حل کرد، استفاده از تایمر است. تایمر کانترها در AVR می توانند تعدادی روتین وقفه داشته باشند. می توان تایمر را طوری تنظیم کرد که هر 4 یا 5 میلی ثانیه یک بار، وقفه ای اتفاق بیفتد. در روتین وقفه می توان کدهای درون تابع SegmentPutsNumber را پیاده کرد. طوری که هر بار وقفه ای اتفاق می افتد، یکی از ارقام نمایش داده شود.

ایجاد تأخیر با تایمر در میکروکنترلرها، می تواند روشی برای نمایش اعداد روی سون سگمنت چند رقمی باشد. با این روش دیگر لازم نیست تابعی برای نمایش روی سون سگمنت در حلقۀ while قرار دهیم. همچنین دیگر نیازی به استفاده از delay نیست. بنابراین می توان در حلقۀ while دستورها و توابع را پشت سر هم و بدون تأخیر اجرا کرد. و این دستورها و توابع تأثیری در نمایش سون سگمنت نخواهند داشت. چشمک زدن سون سگمنت نیز با تنظیم صحیح زمان تایمر، مشاهده نخواهد شد. از طرفی اجرای دستورات دیگر حلقۀ while بدون تأخیر انجام می شود. در صورتی که برای نمایش ارقام از وقفۀ تایمر استفاده شود، نیاز است که متغیر Number به صورت volatile عمومی تعریف شود. دلیل volatile بودن این متغیر در نوشته های «انواع متغیر در C» و «کلاس های حافظه در C و C++» تشریح شده است.

نمایش-عدد-چهار-رقمی

تصویر 8 – نمایش عدد چهار رقمی روی سون سگمنت بدون چشمک زدن

تایمر صفر در AVR

تایمر 2 در AVR

تایمر 1 و 3 در AVR

راه اندازی سون سگمنت با AVR در عمل

در تصویر زیر یک سون سگمنت آند مشترک 4 تایی روی برد توسعۀ ATmega64pin یوبرد قرار گرفته است. نحوۀ اتصال پایه های سون سگمنت به میکروکنترلر، مطابق دیفاین های ابتدای برنامه است. همان طور که مشاهده می شود، عدد 5678 که در برنامه قرار داده ایم، و اعداد دیگر به طور صحیح نمایش داده می شود. با توجه به برنامه ای که نوشتیم، سون سگمنت با فرکانس 62.5 هرتز رفرش می شود. اگرچه با این فرکانس در پروتئوس نتوانستیم عدد را کامل مشاهده کنیم، ولی در عمل، عدد بدون مشکل نمایش داده می شود.

نکته: پایه های سون سگمنت می توانند به هر کدام از پایه های پورت IO متصل شوند. کافی است  DDRx و PORTx و بیت هر پورت در دیفاین های ابتدای برنامه، برای پایه های سون سگمنت تغییر کند.

نکته: راه اندازی سون سگمنت کاتد مشترک نیز مانند راه اندازی سون سگمنت آند مشترک است. در سون سگمنت کاتد مشترک باید مقدار پایۀ مشترک هر رقم، صفر شود. همچنین مقدار قرار گرفته روی پایه های a تا g باید مطابق جدول 1 در ستون Common Cathode باشد.

نمایش-سون-سگمنت-در-عمل

تصویر 9 – نتیجۀ راه اندازی سون سگمنت با AVR روی برد توسعۀ AVR یوبرد

چند تمرین برای راه اندازی سون سگمنت

در این بخش برای درک بهتر مطالب گفته شده چند تمرین طرح می کنیم. بهتر است ابتدا تمرین 1 انجام شود و در تمرین های دیگر از کتابخانه ای که حین تمرین 1 ساخته می شود، استفاده شود. به این شکل اگر در کتابخانه ای که حین تمرین 1 ساخته می شود، ایرادی وجود داشته باشد، در طول تمرین های بعدی برطرف می شود.

تمرین 1 – ساخت کتابخانه برای سون سگمنت: با استفاده از مطالب نوشتۀ «ساخت کتابخانه در C» برای سون سگمنت یک کتابخانه بنویسید. این کتابخانه را طوری بنویسید که اعداد اعشاری را نیز نمایش دهد و صفر قبل از عدد نمایش داده نشود.

تمرین 2 – ساخت شمارنده با سون سگمنت: برنامه ای بنویسید که با استفاده از وقفۀ خارجی و نکات بیان شده در نوشتۀ «وقفه در AVR»، با استفاده از کلیدهایی، یک متغیر کم و زیاد شود و مقدار آن در سون سگمنت نمایش داده شود.

تمرین 3 – ولت متر با سون سگمنت: با استفاده از مطالب نوشتۀ «ADC در AVR» و راه اندازی سون سگمنت با AVR که در این نوشته بررسی شد، یک ولت متر دیجتال و یا یک دماسنج دیجیتال بسازید.

تمرین 4 – سون سگمنت به جای LCD: نمایشگر پروژه ای را که در نوشتۀ «موج سینوسی با AVR و DAC0800» انجام شده است، از LCD به سون سگمنت تغییر دهید.

تمرین 5 – نمایش حروف در سون سگمنت: حروف A و b و C و d و E و F را روی سون سگمنت نمایش دهید.

نمایش-حروف-سون-سگمنت

تصویر 10 – نمایش حروف انگلیسی روی سون سگمنت

نتایج راه اندازی سون سگمنت با AVR

  1. برای نمایش اعداد و برخی حروف روی سون سگمنت، لازم است پایه های سون سگمنت مطابق یک الگو مقدار دهی شوند.
  2. یکی از روش های مقدار دهی به رجیسترهای پورت IO، مقدار دهی با استفاده از ماکروهایی است که نوشتیم. استفاده از این ماکروها خوانایی و درک برنامه را بیشتر می کند. همچنین دیگر نیاز نیست در توابع برنامه به رجیسترها مقدار دهی مستقیم داشته باشیم. این ماکروها هم در کدویژن قابل استفاده اند و هم در اتمل استودیو.
  3. راه اندازی سون سگمنت با کدویژن نیز شبیه راه اندازی سون سگمنت با اتمل استودیو است. در برنامه ای که بررسی کردیم، تنها تفاوت هایی که وجود دارد، نوع تعیین فرکانس میکروکنترلر و سینتکس نوشتاری تابع delay است.
  4. مقدار قرار گرفته روی پایه های سون سگمنت آند مشترک برای نمایش یک عدد، Not شدۀ مقدار مشابه آن برای سون سگمنت کاتد مشترک است.
  5. برای راه اندازی سون سگمنت کاتد مشترک باید پایۀ مشترک صفر شود. برای روشن شدن هر سگمنت نیز باید پایۀ مربوط 1 شود.
  6. برای راه اندازی سون سگمنت آند مشترک باید پایۀ مشترک 1 شود. برای روشن شدن هر سگمنت نیز باید پایۀ مربوط صفر شود.
  7. مناسب ترین راه برای برنامه نویسی سون سگمنت چند رقمی، استفاده از یک تابع برای مقدار دهی به پایه های آن متناسب با مقدار نمایش و یک زمان بندی برای نمایش در ارقام سون سگمنت است. طوری که این زمان بندی تأثیری در اجرای برنامه نداشته باشد و روند برنامه نیز در این زمان بندی تأثیری نداشته باشند.
  8. یکی از راه های زمان بندی نمایش ارقام سون سگمنت در راه اندازی سون سگمنت مالتی پلکس، استفاده از تأخیرهایی است که با وقفۀ تایمر به وجود می آیند.

رضا اسدی

رضا اسدی

مدیر یوبرد، خالق و توسعه دهندۀ پلتفرم یوبرد، مجری پروژه های الکترونیکی، فعال در صنعت آسانسور، سابقه فعالیت در صنعت خودرو و همکاری در صنعت پزشکی و صنایع دیگر، آموزگار آموزش های یوبرد

سفارش پروژه میکروکنترلر یوبرد

زیرساخت مطمئن صنعت

جدیدترین تاپیک های AVR

برنامه-نویسی-میکروکنترلر-ویژوال-استودیو

برنامه نویسی میکروکنترلرها با ویژوال استودیو

نصب VisualGDB روی ویژوال استودیو، ساخت پروژه برای برنامه نویسی میکروکنترلرها با ویژوال استودیو، ساخت پروژه برای STM32 در ویژوال استودیو، کدنویسی STM32 در ویژوال استودیو، ساخت پروژه برای AVR در ویژوال استودیو، ساخت پروژه برای LPC در ویژوال استودیو، ساخت پروژۀ آردوینو در ویژوال استودیو

رله-relay

رله، سوییچ تحریک پذیر

تعریف رله، تاریخچه، طرز کار رلۀ الکترومکانیکی، اصطلاحات، انواع الکترومکانیکی، رلۀ حالت جامد، رلۀ هیبریدی، رلۀ حرارتی و انواع تحریک شونده با عوامل غیر الکتریکی، انواع موجود در صنعت برق و برق صنعتی، رلۀ ایمنی و برخی انواع حفاظتی، رلۀ دیجیتال، لزوم استفاده و راه اندازی رله، مشخصات الکتریکی

پروتکل-i2c-protocol

پروتکل I2C، ادغامی از USART و SPI توسط Philips

پروتکل I2C، تاریخچه I2C، ویژگی ها و کاربردهای I2C، عبارات و اصطلاحات I2C، باس، اتصالات و گسترش شبکه I2C، سیگنال های I2C، قالب داده و آدرس در I2C، انتقال داده در I2C، آدرس دهی 10 بیتی، قابلیت Multi-master، حکمیت، مشخصات الکتریکی و زمانی، مقدار مقاومت های پول آپ، Clock Stretching

سون-سگمنت-seven-segment

سون سگمنت، نمایشگر هفت قسمتی

سون سگمنت چیست؟ انواع 7-segment، تاریخچه 7-segment، ساختار 7-segment و نمایش در آن، تعداد ارقام و 7-segmentهای مالتی پلکس، کاربردها، انواع اندازه ها و رنگ ها و مدار راه اندازی 7-segment، بایاس 7-segment، مقدار مقاومت در راه اندازی 7-segment، درایور سون سگمنت، پایه های 7-segment

28 دیدگاه ها

  1. ضمن عرض سلام. در مورد این متن سوالی داشتم از خدمتتون. در قسمت define کردن پایه ها برای راه اندازی سون سگمنت تعداد زیادی define رو استفاده کردید که
    به نظر میرسه باتوجه به اینکه تعدادشون زیاد شده خود این define ها نیاز به یک روشی برای خوانا کردن و دسته بندی دارن. یا شاید روش بهتری بجز استفاده از define توی این کاربرد باشه که بهتر از استفاده از این تعداد define باشه. ممنون میشم نظرتون رو در این رابطه بفرمایید. تشکر

    پاسخ
    • سلام. یکی از روش های خوانا کردن چنین برنامه هایی اینه که Defineها به کتابخانه های مربوط به خودشون متقل بشن و اونجا دسته بندی بشن. روش های بهتر بسته به کاربرد در پروژه ها مشخص میشه. به عنوان مثال ممکنه در جایی از enum استفاده کنیم. مثل نوشتۀ «روش راه اندازی ADC و LCD گرافیکی KS108 با میکروکنترلرهای AVR». ممکنه کدهای برنامه رو طوری بنویسیم که فقط با یه Define مثلاً پورت LCD رو تغییر بدیم و نیازی نباشه مثل نمونه کد سون سگمنت این نوشته پایه ها رو یکی یکی Define کنیم. باید به این موضوع توجه داشت که توی خیلی از موارد لازم میشه از دستورات پیش پردازنده if# و elif# و … استفاده کنیم. برای مطالبی که گفتم طی نوشته های آینده نمونه کدها و آموزش هایی رو میارم.

      پاسخ
  2. سلام. امروزه باتوجه به نمایشگرهای جدیدتر و پیشرفت نمایشگرها آینده ۷ سگمنت رو چطور میبینید؟

    پاسخ
    • سلام همون طور که توی بخش کاربردهای Seven Segment توضیح داده شد، با توجه به این که توی بعضی کاربردها لازم میشه عدد یا کاراکتری رو با اندازۀ بزرگ نمایش بدیم، میشه از Seven Segment استفاده کرد. راه های دیگه ای هم وجود داره. مثلاً تابلو روان میتونه یه راه برای رفع چنین نیازهایی باشه. ولی قیمت محصول نهایی هم توی استفاده از نمایشگرها دخیله. سون سگمنت قیمت ارزون تری نسبت به تابلو روان داره. شاید از نمایشگرهای دیگه هم بشه استفاده کرد. مثلاً یه عدد یا کاراکتر رو با یه LCD گرافیکی بخوایم نمایش بدیم. طوری که از فاصلۀ چند متری دیده بشه. ولی خب این روش هم نسبت به سون سگمنت از لحاظ قیمت روش گرون تری هستش. به هر حال ارزون بودن سون سگمنت، اندازۀ سون سگمنت، مقدار نوردهی سون سگمنت و … باعث میشه این قطعه همواره در کاربردهایی که نیاز هست عدد و تعدادی کاراکتر محدود نمایش داده بشه، استفاده بشه.

      پاسخ
  3. سلام خسته نباشید ببخشید من برنامه ای در کدویژن نوشتم که باید عدد ۰۰۱۹ روی سون سگمنت ۵ ثانیه نشون داده بشه و سپس این شماره شروع به کم شدن کنه به مدت یک ثانیه یعنی ۰۰۱۸ ، ۰۰۱۷ ، ۰۰۱۶ و…. تا به صفر برسه یعنی ۰۰۰۰
    وقتی به ۰۰۱۰ میرسه بعد کلا صفر میشه و ۰۰۰۹، ۰۰۰۸ ،۰۰۷و …اینارونشون نمیده. استادم گفته باید از sign char استفاده کنم ولی متاسفانه بلدنیسم شما میتونید کمکم کنید؟؟؟ آدرس ایمیلی تلگرامی دارید ک بتونم براتون بفرستم

    پاسخ
    • سلام. خیلی ممنون. یه مقدار روی کدها کار کنید. اول یه تابع بنویسید کلاً برای نمایش روی سون سگمنت 4 تایی. که ورودی رو بگیره و توی سون سگمنت نمایش بده. توی این تابع لازمه ارقام به ترتیب با یه فاصلۀ زمانی مشخص نمایش داده بشن. و بعدش پاک بشن. یه طوری که متوجه پاک شدن نشید و به نظر برسه هر چهار دیجیت با هم روشن هستن. که البته خود شما هم این کار رو کردید و ارقام رو نشون میدید. توی این تابع برای اون فاصلۀ زمانی از دیلی استفاده نکنید. توی نوشتۀ «تاخیر با تایمر در میکروکنترلرها» توضیح دادیم که چطور بدون دیلی و با تایمر یه فاصلۀ زمانی بسازید. با استفاده از تایمر زمان بندی روشن و خاموش شدن دیجیت های سون سگمنت رو انجام بدید. بعد از که این تابع رو نوشتید حالا توی main اول مقدار 19 رو بدید به ورودی تابع سون سگمنتی که نوشتید. بعد یه دیلی 5 ثانیه بذارید. بعد از اون هم یه حلقۀ for بذارید که یه متغیر رو که میذارید توی ورودی تابع، از 18 تا صفر با دیلی 1 ثانیه کم کنه. برای تابع سون سگمنت کدهای همین نوشته رو میتونید استفاده کنید. این که استادتون گفته از signed char استفاده کنید رو منظورش اینه که یه متغیر از این نوع تعریف کنید و نمیدونم دلیلش چی بوده. کمک بنده رو در همین حد قبول کنید. موفق باشید.

      پاسخ
  4. سلام مهندس اسدی. این برو توسعه AVR، سون سگمنت روی خودش سوار میشه؟

    پاسخ
    • سلام. بله. LCD کاراکتری و گرافیکی هم همین طور. و البته ماژول های مختلف دیگه

      پاسخ
  5. سلام. مطلب خیلی خوبی بود. کدها یه مقدار گیج کننده س. چه لزومی داره به این شیوه کد بنویسیم؟ مگه مقدار دهی مستقیم به پایه ها چه ایرادی داره؟ خیلی ممنون

    پاسخ
    • سلام. خواهش میکنم. ما با این شیوه می تونیم پایه های سون سگمنت رو به هر پورتی متصل کنیمو مثلاً a رو وصل کنیم به PA0 و b رو وصل کنیم به PC4. هر طوری که بخوایم. و البته میشه توی برنامه مستقیماً به رجیسترا هم مقدار داد و به این خواسته هم رسید. ولی خب این روش خوانایی بیشتری داره.

      پاسخ
  6. سلام آقای اسدی. تشکر میکنم بابت مطالبی که میذارید. روی برد avr یوبرد میشه سون سگمنت کاتد مشترک هم گذاشت؟

    پاسخ
    • سلام وقت بخیر. خواهش میکنم. بله میتونید قرار بدید.

      پاسخ
  7. سلام. توی سطر اول گفتید که راه اندازی سون سگمنت با میکروکنترلرا معمولاً نیاز به کار با پورت های IO داره. مگه راه دیگه ای هم برای راه اندازیش بدون پورت IO هست؟ ممنونم

    پاسخ
    • سلام. بله. درایورهای سون سگمنتی وجود داره که میشه با I2C یا SPI با اونا ارتباط برقرار کرد. و منظور از این جمله متمایز کردن روش های راه اندازی سون سگمنت با IO و روش های سریال بوده.

      پاسخ
  8. تمرین 1 هم خیلی جالبه. به این فکر نکرده بودم که صفر قبل از عددو نشون ندم

    پاسخ
    • ممنون از نظرتون

      پاسخ
  9. سلام. میشه برای اسکن صفحه کلید هم از این طور ماکروها استفاده کرد؟

    پاسخ
    • سلام. بله میشه. برای صفر و یک کردن پایه ها از ماکروهای همین پروژه استفاده کنید. برای خوندن مقدار یه ورودی هم از مثالا زیر الگو بگیرید.

       

      #define KEYROW1_PIN_NUM       PINE
      #define KEYROW1_BIT_NUM       3
      #define KEYROW1_STATUS        (KEYROW1_PIN_NUM&(1<<KEYROW1_BIT_NUM))
      
      
       if(KEYROW1_STATUS)
       {
        . . . ;
       }
       
      پاسخ
  10. سلام وقت بخیر
    میشه برنامه ای بنویسید که بعد از فشار دادن دکمه start بر روی 7segment از 0 تا 9 با تاخیر ۵۰۰میلی ثانیه شنارش صعودی انجام دهد
    با استفاده از پروتیوس و کد ویژن

    پاسخ
    • سلام. بله میشه. اما این برنامه یه مشکل داره که باید تابع SegmentPutsNumber رو توی حلقۀ while پشت سر هم اجرا کنیم تا خروجی یک عدد رو نشون بده. اول باید این مشکل برطرف بشه. چون برای نمایش شمارش اعداد، باید اجرا شدن توابع وابسته به حلقۀ while نباشه. مثلاً با تایمر میشه این مشکل رو برطرف کرد. بخش «حذف delay» رو مطالعه کنید. روشش اونجا توضیح داده شده.

      پاسخ
  11. سلام خسته نباشید
    در شبیه سازی 7segment علاوه بر داشتن ۷تا مقاومت , چرا از یه مقاومت دیگه هم استفاده میشه , در کلید .?
    (pull down)

    پاسخ
    • سلام. خیلی ممنون. اگه منظورتون این نوشته س که کلاً 8 تا مقاومت برای سون سگمنت گذاشتیم و کلید توی شبیه سازی استفاده نکردیم. این نوشته یک بار ویرایش شده. ممکنه شما فایل پیوست نسخۀ قبلی رو دانلود کرده باشید. برای دریافت فایل پیوست جدید، ممکنه لازم باشه یک بار تاریخچۀ مرورگرتون رو پاک کنید. حالا اون مقاومت هم که پایۀ کلید رو پول آپ یا پول دون کرده (توی فایلی که شما دارید)، برای اینه که مقداری روی پایه قرار بگیره و با فشردن کلید مقدارش تغییر کنه و متناسب با این تغییر کاری انجام بشه.

      پاسخ

یک دیدگاه بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دیگر آموزش های یوبرد

آموزش زبان C و MISRA-C یوبرد

گام نخست دنیای میکروکنترلر

آموزش طراحی PCB و نویز یوبرد

تجسم دنیای الکترونیک

آموزش لحیم کاری و IPC-A-610 یوبرد

ساخت دنیای الکترونیک

آموزش میکروکنترلرهای ARM STM32 یوبرد

شروع بازی ST

آموزش آردوینو یوبرد

جادۀ آسفالت میکروکنترلر

آموزش FreeRTOS یوبرد

زمان واقعی در میکروکنترلر و پردازنده های کوچک با FreeRTOS

آموزش ماژول های SIM800 یوبرد

تلفن همراه صنعت

آموزش زبان ++C و ++MISRA-C یوبرد

لمس شی گرایی در میکروکنترلرها

آموزش میکروکنترلرهای LPC یوبرد

یادگار فیلیپس

آموزش های شاخص

دانلود

لطفا برای دریافت لینک دانلود اطلاعات خواسته شده را وارد نمایید
ضبط پیام صوتی

زمان هر پیام صوتی 4 دقیقه است