Virgool - ویرگول

آموزش ریزپردازنده (ساعت با قابليت تنظيم توسط سوئیچ و کیپد)

by

نام پروژه :

آموزش گام به گام ساخت ساعت ديجيتالي روی سون سگمنت

اجزاي مدار :

ATMEGA8L-CRYSTAL(32.768KHZ)-74HC245-R220Ω-7segCC-Sowitch-Keypad4*4

زبان برنامه نويسي :

C

عملکرد مدار :

نام استاد :

جناب آقای مهندس یعقوبی تبار

تهیه کننده :
محمد جواد رهسپار یگانه

مقدمه

در این پروژه ما قصد داریم توسط (real time clock) rtc میکروکنترلر avr تحت کامپایلر قدرتمند codevisionیک ساعت بسازیم و آن را روی سون سگمنت به روش مولتی پلکس به نمایش در آوریم . در اکثر میکروکنترلرهای avr ، تایمر دو می تواند به عنوان rtcعمل کند که در اینصورت کلاک مورد نیاز آن به صورت آسنکرون از طریق یک کریستال ساعت 32.768KHZ تامین می گردد .

عملکرد روش مولتی پلکس :

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

عملکرد تایمر دو :
به طور کلی عملکرد تایمر دو مشابه عملکرد تایمر صفر می باشد ؛ با این تفاوت که نمی توان به عنوان کانتر از آن استفاده نمود ؛ اما می توان با اتصال یک کریستال ساعت 32.768KHZ به پایه های ,TOCS1 TOCS2 از آن در وضعیت آسنکرون جهت rtcاستفاده نمود . تایمر دو خود دارای یک prescaler مجزا از بقیه تایمرها می باشد ؛ که با تقسیم فرکانس ایجاد شده توسط کریستال 32.768KHZ بر 128 می توان به زمان سرریز یک ثانیه که مناسب برای عملکرد ساعت است دست پیدا کرد .
پیکربندی تایمر دو توسط جادوگر :
بزرگترین مزیت کامپایلر codevision نسبت به بقیه کامپایلرهایی که برنامه نویسی در محیط آنها به زبان c می باشد وجود codewizard یا جادوگر می باشد ، زیرا شما بدون نیاز به دانش زیاد می توانید ماژول های avr را به راحتی پیکربندی کنید . که در اینجا ما نیز می خواهیم تایمر دو را در مد آسنکرون توسط جادوگر پیکربندی کنیم .
ابتدا وارد محیط جادوگر شده سپس وارد زبانه Timer2 شوید و clock source را از system clock به TOSC1 pin تغییر دهید که در اینصورت کلاک تایمر دو جدا از کلاک سیستم و به صورت آسنکرون از روی پایه های TOSC1 , TOSC2 تامین می گردد .

حال باید مقدار clock value را روی PCK2/128 قرار دهیم .که در صورت استفاده از کریستال 32.768 کیلو هرتز روی پایه های TOSC1,TOSC2 می توان به سرریز یک ثانیه دست پیدا کرد و تایمر دو را به rtcیا ساعت زمان واقعی تبدیل کرد و با انتخاب تیک overflow interrupt می توان وقفه تایمر دو را فعال کرد که پس از سر ریز یک ثانیه وقفه اتفاق می افتد .

شرح سخت افزار :
در این مدار atmega8 هسته اصلی می باشد و وظیفه تمامی محاسبات را بر عهده دارد . 74HC245آی سی بافر است و نقش ایزوله کردن و تقویت جریان را دارد ، البته خروجیهای AVR توانایی روشن کردن LEDرا به صورت مستقیم دارند اما در صورت استفاده از سون سگمنت در ابعاد بزرگتر باید از بافر استفاده شود . مقاومتهای 220 اهم برای محافظت از سون سگمنتها در برابر اضافه جریان قرار داده شده است . کریستال 32.768 khz کلاک تایمر دو را بصورت آسنکرون برای رسیدن به سرریز یک ثانیه تامین می کند و کلاک اصلی برنامه توسط نوسانساز RC داخلی که روی 8Mhz قرار داده شده تامین می گردد. برای نمایش اعداد از یک سون سگمنت شش تایی از نوع کاتد مشترک استفاده شده همچنین برای کاهش سخت افزار می توان از قسمت نمایش ثانیه صرف نظر کرده و از یک سون سگمنت چهارتایی استفاده کرد ، برای نمایش ساعت نیاز است که اعداد به کد معادل برای سون سگمنت تبدیل شوند به این منظور آی سی های دیکودر BCD TO 7S با نام های 7448 برای سون سگمنت های کاتد مشترک و 7447 برای سون سگمنت های آند مشترک بکار برده می شود که ما برای کاهش سخت افزار به صورت نرم افزاری کدهای معادل برای سون سگمنت را تبدیل کرده ایم و دیگر نیازی به استفاده از آی سی های دیکودر نیست . برای تنظیم کردن ساعت نیز از سه سوئیچ استفاده شده .

شرح نرم افزار :
به طور کلی برنامه از چهار قسمت اصلی تشکیل شده :

1. تابع mainکه پیکره اصلی برنامه است .
2. زیربرنامه وقفه تایمر دو که هر ثانیه یک بار اتفاق می افتد .
3. تابع set_time که وظیفه کلید خوانی و تنظیم مقادیر ثانیه ، دقیقه و ساعت را بر عهده دارد .
4. تابع display که وظیفه نمایش و اسکن اعداد را بر عهده دارد .

شروع برنامه :

#include <mega8.h>

#include <delay.h>

در این قسمت ما توسط دستور پیش پردازنده #include فایلهای هدر مربوط به mega8 و delay را به برنامه خود اضافه می کنیم .

__________________________________________________________________________________________

#define data_port PORTD

#define comm_port PORTC

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

void set_time(void);

void display(void);

در این قسمت دو تابع با نامهای set_time , display تعریف شده است .

__________________________________________________________________________________________

flash char cathode_seg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//------------------------------------------0------1------2-------3-------4------5-------6------7-------8------9---

در این قسمت کد های معادل سون سگمنت از نوع کاتود مشترک را درون یک آرایه تعریف کرده ایم و چون این مقادیر ثابت هستند و در طول برنامه تغییر نمی کنند می توان آنها را درون حافظه فلش تعریف کرد که برای این کار باید از کلمه کلیدی const یا flash استفاده کرد .

signed char second=0,minute=0,hour=0;

در این قسمت سه متغییر از نوع char علامتدار با نامهای second ، minute ، hourبرای مقادیر ثانیه ، دقیقه و ساعت تعریف شده است . اگر متغییر های ما از نوع علامت دار نباشند هنگامی که برای تنظیم ساعت از کلید down استفاده شود و عدد ما به مقدار کوچکتر از صفر برسد برنامه با مشکل مواجه شده . همچنین می توان در این قسمت از برنامه مقادیر ثانیه ، دقیقه و ساعت را مقدار دهی اولیه کرد .

__________________________________________________________________________________

unsigned char key,dot,pointer;

در این قسمت سه متغییر از نوع char بدون علامت با نامهای key , dot و pointerتعریف شده است که متغییر key مقدار کلید خوانده شده را در خود جای می دهد و متغییر dot وظیفه تفکیک ثانیه ، دقیقه و ساعت را در بخش تنظیم ساعت بر عهده دارد و متغییر pointer. نقش چشمک زدن پوینتر بین اعداد (ساعت – دقیقه) و (دقیقه – ثانیه) را به نشانه وقوع هر یک ثانیه بر عهده دارد

__________________________________________________________________________________

unsigned char dot_set_min,dot_set_hour,dot_set_sec;

در این قسمت سه متغییر از نوع char بدون علامت تعریف شده که در این متغیرها تنها بیت با ارزش آنها برای ما حائض اهمیت است(0b00000000) و هر کدام نقش روشن کردن پوینترهای مربوط به ثانیه ، دقیقه و ساعت را در هنگام تنظیم ساعت بر عهده دارند .

__________________________________________________________________________________________

تابع main :

این قسمت شروع تابع اصلی برنامه با نام main است و درون آن رجیسترهای I/O مقداردهی اولیه می شوند .

voidmain(void)

{

PORTB=0x00;
DDRB=0x00;

در این قسمت PORTB به عنوان درگاه ورودی تعریف شده است .

PORTC=0x00;
DDRC=0xFF;
PORTD=0x00;
DDRD=0xFF;

در این قسمت PORTC و PORTD به عنوان درگاه خروجی تعریف شده اند .

ASSR=0x08;
TCCR2=0x05;
TCNT2=0x00;
OCR2=0x00;
TIMSK=0x40;

در این قسمت رجیسترهای مربوط به تایمر دو با توجه به تنظیماتی که توسط جادوگر انجام داده ایم مقدار دهی شده اند .

#asm("sei")

این دستور وقفه سراسری را فعال سازی می کند .

while (1)

{

set_time();
display();

}

}

در این قسمت توسط دستور while یک حلقه نامتناهی ایجاد شده که درون آن توابع set_time , display دائماً فراخوانی می شوند .

__________________________________________________________________________________________

زیر برنامه وقفه تایمر دو :

در این قسمت زیر برنامه وقفه تامر دو قرار دارد که پس از سرریز تایمر در هر یک ثانیه برنامه به این قسمت پرش خواهد کرد .این زیر برنامه وظیفه محاسبه زمان را بر عهده دارد .

interrupt [TIM2_OVF] void timer2_ovf_isr(void)

{

if(dot==0) {

در این قسمت از برنامه متغیر dot با مقدار صفر مقایسه می شود که اگر ما در قسمت زیر برنامه set_time کلیدی را فشرده باشیم مقدار متغیر dotتغییر خواهد کرد و در اینجا عمل محاسبه زمان انجام نمی شود و از زیر برنامه خارج خواهیم شد.

Pointer = ~pointer & 0b10000000;

در این قسمت متغییر pointer در هر یک ثانیه که زیر برنامه اجرا می شود تغییر وضعیت داده و پوینترهای چشمکزن را خاموش و روشن می کند .

second++;

if (second > 59)

{

second=0;
minute++;

if (minute>59)

{

minute=0;
hour++;

if(hour>23)

{

hour=0;

}

}

}

};

}

زیر برنامه تابع set_time :
در این قسمت زیر برنامه تابع set_time قرار دارد که عمل کلیدخوانی در آن صورت می پذیرد و شامل سه بخش اصلی می شود :
1. فشرده شدن کلید set که با هر بار فشرده شدن هر کدام از قسمتهای ثانیه ، دقیقه یا ساعت را قابل تنظیم می کند .
2.فشرده شدن کلید up در صورتی عمل می کند که قبل از آن توسط کلید set یکی از قسمتهای ثانیه ، دقیقه یا ساعت را انتخاب کرده باشیم و با هر بار فشرده شدن یک واحد به مقادیر ثانیه ، دقیقه یا ساعت می افزاید .
3. فشرده شدن کلید down در صورتی عمل می کند که قبل از آن توسط کلید set یکی از قسمتهای ثانیه ، دقیقه یا ساعت را انتخاب کرده باشیم و با هر بار فشرده شدن یک واحد از مقادیر ثانیه ، دقیقه یا ساعت می کاهد .

void set_time(void)

{

key=PINB & 0b00000111;

در این قسمت PINB با مقدار 0b00000111 ، and منطقی شده و حاصل درون متغیر key قرار می گیرد که اگر متغیر key برابر با صفر باشد نشانگر این است که هیچ کلیدی فشرده نشده .

switch(key) {

/////press set button

case 0b00000001:

در این قسمت اگر متغیر keyبرابر با مقدار 0b00000001 باشد نشانگر این است که کلید set فشرده شده است که با هر بار فشرده شدن کلید key، متغیر dot یک واحد افزایش می یابد .

dot++;

switch (dot) {

case 1 :

dot_set_sec =0b10000000;
dot_set_min =0b00000000;
dot_set_hour=0b00000000;

pointer=0;

break;

در این قسمت اگر متغیر dot برابر با مقدار 1 باشد پوینتر مربوط به تنظیم ثانیه مقداردهی شده و مقدار ثانیه قابل تنظیم خواهد بود و همچنین متغیر pointer برابر با صفر می شود که در اینصورت پوینترهای چشمکزن خاموش می شوند . __________________________________________________________________________________________

case 2:

dot_set_sec=0b00000000;
dot_set_min=0b10000000;
dot_set_hour=0b00000000;

pointer=0;

break;

در این قسمت اگر متغیر dot برابر با مقدار 2 باشد پوینتر مربوط به تنظیم دقیقه مقداردهی شده و مقدار دقیقه قابل تنظیم خواهد بود و همچنین متغیر pointer برابر با صفر می شود که در اینصورت پوینترهای چشمکزن خاموش می شوند . __________________________________________________________________________________________

case 3:

dot_set_sec =0b00000000;
dot_set_min =0b00000000;
dot_set_hour=0b10000000;

pointer=0;

break;

در این قسمت اگر متغیر dot برابر با مقدار 3 باشد پوینتر مربوط به تنظیم ساعت مقداردهی شده و مقدار ساعت قابل تنظیم خواهد بود و همچنین متغیر pointer برابر با صفر می شود که در اینصورت پوینترهای چشمکزن خاموش می شوند . __________________________________________________________________________________________

default:

if (dot >= 4) {

dot_set_sec =0b00000000;
dot_set_min =0b00000000;
dot_set_hour=0b00000000;

dot=0;

}

};

break;

در این قسمت اگر متغیر dot بزرگتر یا مساوی با مقدار 4 باشد هیچ کدام از پوینترها مقداردهی نمی شوند و همچنین متغیر dot برابر با صفر می شود که در اینصورت برنامه از حالت تنظیم خارج می شوند . __________________________________________________________________________________________

/////press up button

case 0b00000010:

در این قسمت اگر متغیر keyبرابر با مقدار 0b00000010 باشد نشانگر این است که کلید up فشرده شده است و در صورتی کلید upکارایی خواهد داشت که قبلاً توسط کلید set یکی از قسمتهای ثانیه ، دقیقه یا ساعت جهت تنظیم انتخاب شده باشند .

switch (dot) {

case 1 :

second++;
if (second>59) second=0;

break;

در این قسمت اگرمتغییر dot برابر با مقدار 1 باشد یک واحد به ثانیه اضافه می شود و اگر مقدار آن بزرگتر از 59شود مساوی صفر می گردد.
__________________________________________________________________________________________

case 2 :

minute++;
if
(minute>59) minute=0;

break;

در این قسمت اگرمتغییر dot برابر با مقدار 2 باشد یک واحد به ثانیه اضافه می شود و اگر مقدار آن بزرگتر از 59شود مساوی صفر می گردد.
__________________________________________________________________________________________

case 3:

hour++;
if(hour>23) hour=0;

break;

};

در این قسمت اگرمتغییر dot برابر با مقدار 3 باشد یک واحد به ثانیه اضافه می شود و اگر مقدار آن بزرگتر از 59شود مساوی صفر می گردد.
__________________________________________________________________________________________

break;

/////press down button

case 0b00000100:

در این قسمت اگر متغیر keyبرابر با مقدار 0b00000100 باشد نشانگر این است که کلید down فشرده شده است و در صورتی کلید downکارایی خواهد داشت که قبلاً توسط کلید set یکی از قسمتهای ثانیه ، دقیقه یا ساعت جهت تنظیم انتخاب شده باشند .

switch (dot) {

case 1 :

second--;
if (second<0) second=59;

break;

در این قسمت اگرمتغییر dot برابر با مقدار 1 باشد یک واحد از ثانیه کاسته می شود و اگر مقدار آن کوچکتر از صفر شود مساوی 59می گردد.
__________________________________________________________________________________________

case 2 :

minute--;
if
(minute<0) minute=59;

break;

در این قسمت اگرمتغییر dot برابر با مقدار 2 باشد یک واحد از دقیقه کاسته می شود و اگر مقدار آن کوچکتر از صفر شود مساوی 59 می گردد.
__________________________________________________________________________________________

case 3:

hour--;
if(hour<0) hour=23;

break;

};

در این قسمت اگرمتغییر dot برابر با مقدار 3 باشد یک واحد از ساعت کاسته می شود و اگر مقدار آن کوچکتر از صفر شود مساوی 23 می گردد.
__________________________________________________________________________________________

break;

};

}

زیر برنامه تابع display :

در این قسمت ، زیر برنامه تابع display قرار دارد که وظیفه آن نمایش اعداد ثانیه ، دقیقه و ساعت بر روی سون سگمنت است و در آن سعی شده تمامی دستورات مربوط به نمایش هر عدد در یک خط نوشته شود تا به خوانایی و سادگی برنامه بیافزاید . در اینجا برای نمایش هر یک از اعداد ثانیه ، دقیقه و ساعت نیاز است که قسمتهای یکان و دهگان هر عدد بصورت مجزا از یکدیگر تفکیک شوند که جهت این امر از الگوریتمی بسیار ساده استفاده شده به عنوان مثال اگر مقدار ساعت برابر با عدد23 باشد برای جدا کردن رقم دهگان آن کافی است تا عدد 23را توسط عملگر / بر عدد 10 تقسیم کنیم 23 /10=2.3 و چون متغییر hourاز نوع flout تعریف نشده فقط مقدار صحیح آن که عدد 2 باشد برگردانده می شود و برای جدا کردن رقم یکان کافی است تا عدد 23 را توسط عملگر % بر عدد 10 تقسیم کنیم 23%10=2.3 که در اینصورت فقط مقدار باقیمانده تقسیم که عدد 3 است برگردانده می شود و اعداد حاصل از تقسیم به عنوان عدد آرایه cathode_seg به کاربرده می شوند به این دستور data_port=cathode_seg [hour/10] دقت کنید ؛ با توجه به مثال فوق خواهیم داشت data_port=cathode_seg [2] و این دستور دومین عدد از آرایه cathode_seg را که کد عدد دو (0X5B) برای سون سگمنت است به data_port ارسال می کند . در ادامه برای نمایش عدد 2 بر روی سون سگمنت باید توسط دستور comm_port=0b11111110 سون سگمنت متناظر با رقم دهگان ساعت روشن شود و توسط دستور delay_ms(4)برای مدت چهار میلی ثانیه عدد 2 روی سون سگمنت نمایش داده می شود و در نهایت توسط دستور comm_port=0xff سون سگمنت خاموش شده و آماده نمایش عدد بعد می شود ؛ اگر ما توسط دستور comm_port=0xff سون سگمنت را خاموش نکنیم و عدد بعد را ارسال کنیم چون هنوز comm_port ما برای نمایش عدد قبلی روشن است برای لحظات کوتاهی عدد جدید را نشان خواهد داد و در عمل باعث می شود یک سایه از عدد قبل را بر روی سون سگمنتها داشته باشیم ؛ که این امر هنگام شبیه سازی در نرم افزار پروتئوس مشهود نمی باشد.
حلقه for در زیر برنامه displayروی نمایش اعداد بی تاثیر است و برای ایجاد یک تاخیر در عمل کلید خوانی بکار برده شده اگر این تاخیر ایجاد نشود چون زیر برنامه های set_timeو display به صورت مداوم و با سرعت بالایی در حال اجرا هستند وقتی ما کلیدی را بفشاریم تا زمانی که کلید را رها کنیم چندین بار زیر برنامه set_time اجرا می شود و کنترل دقیقی روی تنظیم مقادیر ساعت را نخواهیم داشت به همین منظور می توان با مقدار دهی متغییر i در حلقه for میزان تاخیر در کلید خوانی را تغییر داد .

void display(void)

{

unsigned char i;

for(i=0;i<10;i++){

data_port=cathode_seg[hour/10] | dot_set_hour; comm_port=0b11111110;delay_ms(4);comm_port=0xff;

data_port=cathode_seg[hour%10] | dot_set_hour | pointer;comm_port=0b11111101;delay_ms(4);comm_port=0xff;

data_port=cathode_seg[minute/10] |dot_set_min; comm_port=0b11111011;delay_ms(4);comm_port=0xff;

data_port=cathode_seg[minute%10] | dot_set_min | pointer; comm_port=0b11110111;delay_ms(4);comm_port=0xff;

data_port=cathode_seg[second/10] |dot_set_sec ; comm_port=0b11101111;delay_ms(4);comm_port=0xff;

data_port=cathode_seg[second%10] | dot_set_sec; comm_port=0b11011111;delay_ms(4);comm_port=0xff;

};

}

ساعت دیجیتال روی سون سگمنت با قابلیت تنظیم توسط keypad
شرح سخت افزار :

در این مثال برای تنظیم ساعت از کیپد 4*4 استفاده شده . برای عمل کلید خوانی از روش wakeup یا interrupt استفاده گردیده که در این روش نیاز به چهار عدد دیود معمولی 1n4148می باشد که در ادامه مختصرا به آن خواهیم پرداخت .

عملکرد روش wakeup در کلید خوانی :
در این روش با استفاده از چهار عدد دیود معمولی 1n4148 سطرهای کیپد ( P.0 تا P.3) را به یکی از وقفه های خارجی میکروکنترلر وصل می کنیم و با فعال سازی وقفه خارجی ، هنگامی که کلیدی فشرده شود زیر برنامه وقفه خارجی اتفاق می افتد و با نوشتن دستورات مربوط به کلید خوانی در زیر برنامه وقفه ، مقدار کلید فشرده شده را بدون نیاز به سرکشی دائم و اشغال شدن cpu میکروکنترلر بدست می آوریم .

شرح نرم افزار :
ابتدا با استفاده از چهار عدد دیود 1n4148 پینهای صفر تا سه از پورتی که کیپد به آن متصل شده را مطابق شکل به پایه INT0 میکروکنترلر وصل کنید . سپس PIND.2 که ورودی وقفه خارجی صفر است را به عنوان ورودی و مقاومت poll up آن را فعال نموده و وقفه خارجی صفر را در مد low level قرار دهید .

پیکره اصلی این برنامه همانند برنامه قبلی می باشد ، فقط به بخشهایی که به برنامه تنظیم ساعت با کیپد اضافه شده می پردازیم . برنامه کلید خوانی به صورت جداگانه در یک فایل هدر با نام keypad.h و فایل کتابخانه ای keypad.lib نوشته شده که در کنار فایل پروژه قرار داده شده .

برای سادگی و خوانا بودن پیکربندی keypadروی پورت مورد نظر ، از الگوی پیکربندی lcd کاراکتری که در ورژن های قدیمیتر کدویژن و به زبان اسمبلی استفاده می شد بکار رفته . که در این پروژه کیپد به پورت Bمتصل شده .

بعد از اجرای برنامه در صورتی که هرکدام از کلید های کیپد را بفشارم به زیر برنامه وقفه خارجی ارجاع داده می شویم ، اگر کلید فشرده شده set time (‘D’) باشد ، متغییر dotمقدار دهی می شود که با هر بار فشرده شدن پوینتر های مربوط به مقادیر ساعت ، دقیقه یا ثانیه نیز روشن می شود و منتظر می ماند تا مقادیر جدید را وارد کنیم . این بخش از برنامه همانند برنامه set timeدر بخش تنظیم ساعت با سوئیچ می باشد .

اگر کلید فشرده شده یکی از کلید های ‘B’ , ‘C’ , ‘*’ , ‘#’ باشد ، از زیر برنامه وقفه خارج می شویم چون ما برنامه ای برای آنها ننوشته ایم و فعلا بلا استفاده می باشند ، اما خود می توانید برای آنها کارایی تعریف کنید برای مثال یک برنامه آلارم به ساعت خود اضافه کنید .

اگر کلید فشرده شده یکی از اعداد 0 تا 9 باشد ، به بخش defaultوارد می شویم . و با توجه به مقدار متغییر dot که توسط کلید set time قبلا مقدار دهی شده مقادیر ساعت مقداردهی می شوند .

اگر مقدار متغییر dot برابر 1 باشد مقدار ساعت قابلیت تنظیم خواهد داشت . مقدار کلید فشرده شده که درون متغییر key قرار دارد درون متغییر Hبارگزاری می شود و چون ماکزیمم مقدار ساعت باید عدد 23 باشد و نباید از این مقدار تجاوز کند ، رقم دهگان ساعت با عدد 2 مقایسه می شود و اگر بزرگتر از عدد 2 باشد آن را صفر می کنیم و رقم یکان ساعت نیز با عدد 3 مقایسه می گردد و در نهایت عدد ساعت ما مقداردهی می شود .

اگر مقدار متغییر dot برابر 2 باشد مقدار دقیقه قابلیت تنظیم خواهد داشت . مقدار کلید فشرده شده که درون متغییر key قرار دارد درون متغییر Mبارگزاری می شود ، یک متغییر به نام hold نیز وجود دارد که در ابتدا با عدد صفر مقدار دهی شده . که رقم خوانده شده از صفحه کلید درون این متغیر نیز قرار می گیرد این متغییر در واقع رقم یکان را درون خود جای می دهد و چون ماکزیمم مقدار دقیقه نباید از عدد 59 تجاوز کند ، یعنی رقم دهگان نباید از عدد 5 بزرگتر باشد ، بنابراین با عدد 5 مقایسه شده و اگر این عدد بزرگتر از عدد 5 باشد آن را صفر می کند سپس این عدد را در عدد 10 ضرب می کند تا به رقم دهگان انتقال یابد و در نهایت عدد دقیقه ما مقداردهی می شود .

اگر مقدار متغییر dot برابر 3 باشد مقدار ثانیه قابلیت تنظیم خواهد داشت و دقیقا همانند تنظیم دقیقه عمل می کند .

اگر کلید فشرده شده ‘A’ باشد ، برنامه از بخش تنظیم خارج خواهد شد .

* با تشکر از لطف و زحمات شما استاد گرانقدر *