الوصف(Description):-
الميكروكونترولر
PIC مجهز بنظام أو أكثر للتوقيت الدقيق يعرف باسم
المؤقتات Timers والتى يمكن استخدامها لتنفيذ مجموعة متنوعة
من وظائف التوقيت الدقيقة مثل توليد أحداث في أوقات محددة ، وقياس مدة (فترة دوام)
duration حدث وحفظ
تسجيل التاريخ والوقت وعد الأحداث counting وما إلى ذلك.العنصر
الرئيسي فى وحدة (موديول) المؤقت هو عداد ثنائى حر يتزايد عند كل نبضة ترد إليه .
ونظرا لأنه يعمل بشكل مستقل فإنه يمكن أن يعد النبضات فى وقت واحد (بالتزامن) مع
تنفيذ البرنامج الرئيسي.يمتلك
الميكروكونترولر PIC16F88 ثلاثة من المؤقتات
كأجهزة hardware مدمجة به
وتسمى :Timer0 و Timer1و Timer2 وسوف
نتناول فى هذا التدريب وحدة (موديول) المؤقت
Timer0.
المعلومات النظرية المطلوبة ( Required Theory)
معلومات عن وحدة (موديول)
المؤقت Timer 0
وحدة
(موديول) المؤقت / العداد timer/counter
module ببساطة هى عداد ثنائى binary counter مستقل والذى يمكن تهيئته (إعداده) لكى يقوم بعد
نبضات ساعة دورات التعليمات الداخلية أو عد نبضات ساعة خارجية .
المؤقت Timer 0 هو عداد متزامن بسعة 8 خانات
8-bit والذى يقوم بحفظ
(تخزين) قيمة العداد فى سجل وظائف خاصة يسمى TMR0 . هذا السجل قابل
للقراءة وللكتابة فى أى وقت عن طريق البرنامج . إذا كتبت قيمة عليه فسوف يبدأ
العداد التزايد من هذه القيمة .عندما يتم تشغيل الموديول Timer 0 بنبضات ساعة تعليمات
المعالج فيقال أنه يعمل كمؤقت timer لأنه يتزايد بمعدل ثابت ( يتحدد بنبضات ساعة
المعالج) , وإذا علمت عدد النبضات التى قام بعدها يمكنك إشتقاق (إستنتاج) الوقت
المنقضى .
يمكن للمؤقت
Timer 0 أيضا عد النبضات
الخارجية الواصلة إلى الطرف RA4(pin3) واسمه البديل هو : T0CKI (Timer Zero Clock Input) " مدخل نبضات الساعة للمؤقت صفر "
. عندما يقوم الموديول بعد النبضات الخارجية يقال أنه يعمل كعداد counter . سوف نناقش نظامى
العمل كل على حدة .
نظام المؤقت Timer mode
·
يتم اختيار نظام المؤقت بمسح clear الخانة TOCS (OPTION
register, bit 5) .
·
فى نظام المؤقت يتزايد السجل TMR0 عند
كل دورة تعليمة . ولأن هذا السجل ذو سعة 8-bit فيمكنه
العد من الصفر 00 إلى FF (255) , وعندما
يصل إلى أقصى قيمة له وهى FF
(255) ويتقدم فى التزايد فيلف العد عائدا إلى الصفر 00 وتعرف هذه
الحالة بالطفحان overflow (تجاوز الحد الأقصى) ويتم تسجيلها بواسطة الخانة T0IF (Timer0 Interrupt Flag) بالسجل INTCON (Interrupt Control) بجعلها بالقيمة set
أى 1 , حيث
يمكن لهذه الحالة بدء (توليد) مقاطعة والتى تعرف باسم " المقاطعة بالمؤقت صفر
" Timer0 Interrupt إذا ما كانت ممكنة
لعمل مقاطعة .
·
يتم تمكين المقاطعة بالمؤقت Timer 0 بجعل الخانة T0IE (Timer0 Interrupt Enable) "
تمكين المقاطعة بالمؤقت صفر " بسجل التحكم فى المقاطعة INTCON بواحد أى set بالأضافة إلى خانة
التمكين العام GIE . هذه المقاطعة هى
التى يجب أن تبين أن الوقت إنتهى وتحدث عند حدوث طفحان بالسجل TMR0 .
·
يجب مسح clear الخانة
TOIF " علم المقاطعة
بالمؤقت صفر " بواسطة روتين خدمة المقاطعة بحيث يمكن حدوث مقاطعة بالمؤقت من
جديد .
·
نفترض أن الميكروكونترولر PIC يعمل على مذبذب ساعة
بتردد Fosc =4 MHz فإن تردد نبضات ساعة التعليمات سوف تكون Fosc /4 = 1 MHz . نتيجة لذلك يقوم
العداد بالتزايد كل واحد ميكروثانية 1 μs بالضبط .وهذا يعنى أن
المؤقت Timer 0 سوف
يستغرق 256 μs لكى يعد من الصفر إلى
الصفر التالى . عن طريق تحميل سجل المؤقت TMR0 بقيمة مسبقة مناسبة
يمكن اختيار فترات زمنية أصغر .على سبيل المثال إذا تم تحميل السجل TMR0 مسبقا بالقيمة 206 فإن المؤقت Timer 0 سوف يحدث له طفحان
بعد 50 μs فقط والسؤال
ماذا اذا اردنا زمن كبر من 256 ميكرو ثانيه الاجابه في النقطه التاليه
·
علاوة على ذلك يوجد قاسم تردد مبرمج بسعة 8-bit يعرف باسم prescaler "المقياس المسبق " أو " معامل القسمة "
وهو متاح لقياس الفترات الزمنية الطويلة . والمقياس المسبق هو دائرة قسمة تقع بين
مصدر نبضات الساعة والمؤقت وتقوم بقسمة التردد الداخل على قيمة من ثمانى قيم ثنائية
تقع ما بين القيمة 2 والقيمة 256 .إذا كان
تردد نبضات ساعة التعليمات 1MHz فإن أقصى
فترة زمنية سوف تكون
256 x 256 μs = 65.536 ms
وهى التى تناظر معمل قسمة 256 . قيم
معامل القسمة يتم اختيارها برمجيا بواسطة الخانات PS0, PS1,PS2 " خانات اختيار معامل القسمة "
بالسجل OPTION .
من أجل تخصيص استخدام معامل
القسمة مع موديول المؤقت Timer 0 يجب مسح clear = 0 الخانة PSA " تخصيص معامل
القسمة " . إما إذا كانت الخانة PSA بواحد set = 1 فلا يتم تخصيص أى معامل قسمة
لموديول المؤقت .
نظام العداد Counter Mode
·
يتم اختيار نظام العداد بجعل الخانة TOCSبالسجل OPTION بواحد set = 1 .
·
فى هذا النظام يقوم موديول المؤقت Timer 0 بعد نبضات الساعة
الخارجية الموجودة على الطرف RA4/T0CKI.
·
سوف يتزايد المؤقت سواء عند الحافة الصاعدة
أو عند الحافة الهابطة لنبضات الساعة والتى يتم اختيار ذلك برمجيا بواسطة الخانة T0SE (Timer0 Source Edge) " حافة مصدر المؤقت صفر " بالسجل OPTION .فإذا كانت هذه
الخانة بواحد set فسوف
يتزايد المؤقت عند الحافة الهابطة لكل نبضة من نبضات الساعة التى تصل إلى
الطرف RA4/T0CKI . مرة أخرى يمكن
توسعة أو تمديد مدى العداد باستخدام prescaler .
مخطط الدائرة (Circuit Diagram)
البرنامج (Software)
sbit LED at RB0_bit;
unsigned short Num;
void interrupt() {
Num ++;
if(Num == 18) {
LED = ~LED; // Toggle LED every sec
Num = 0;
}
TMR0 = 39;
INTCON.TMR0IF
= 0;
}
void main() {
CMCON = 0x07 ; //
Disbale comparators
TRISB
= 0b00000000; // PORTB All Outputs
TRISA
= 0b00100000; // PORTA All Outputs, Except RA5=MCLR
LED = 0;
Num = 0;
OPTION_REG = 0x07; // Prescaler (1:256) is assigned to
the timer TMR0
TMR0 = 39; // Timer T0 counts from 39 to 255
INTCON = 0xA0; // Enable interrupt TMR0 and Global Interrupts
do {
} while(1); }
|
شرح البرنامج
فى البداية سوف ننشأ زمن تأخير
بقيمة واحد ثانية تقريبا باستخدام موديول المؤقت Timer 0 كمؤقت . الميكروكونترولر يعمل على تردد ساعة المذبذب Fosc = 4MHz لذلك يكون الزمن الدورى للتعليمة هو 1 μs
. لتوليد فترة تأخير زمنى قدرها ثانية يجب أن يعد المؤقت مليون 1000000
دورة تعليمة . فإذا استخدمنا معامل القسمة prescaler بالقيمة 256
فإن العدد المطلوب يقل من مليون إلى )
(1000000/256
= 3906
بمعني اخر اي انه كل مليون نبضه تعليمه سوف
يخرج
prescaler حوالي 3906 نبضه . والآن إذا حملنا السجل TMR0
بالقيمة المسبقة 39 فإن طفحانه سوف يحدث بعد 256-39 = 217 counts مع
ملاحظه ان هذا الطفحان سوف يحدث بعد 217 نبضه من نبضات prescaler وهكذا تكون عدد مرات الطفحان المطلوبة 3906/217 = 18
. بهذه الإعدادات فإنه بعد 18 مرة
طفحان للسجل TMR0 (وفى كل مرة يتم تحميله مسبقا بالقيمة 39
) ينقضى فترة زمنية قدرها واحد ثانية تقريبا .
البرنامج يوظف هذا التأخير فى
عمل وميض لليد .
تطوير البرنامج(1)
نريد ان نطور البرنامج بحيث اننا
يمكننا قياس الثواني والدقائق حيث اننا سوف نستخدم عدد 2 ليد ضوئي الاول يتغير
حالته كل ثانيه اما الاخر فيتغير حالته كل دقيقه ولعمل هذا التطوير يجب اولا عم
مجموعهمن الحسابات لحساب كيف يمكن للتيمر ان يعد الدقائق كما يلي مما سبق حيث اننا
لتوليد فتره زمنيه مقدارها ثانيه كنا نحتا ج الي مليون دوره تعليمهاما هنا فنحتاج
الي دقيقه فيتم ضرب المليون دوره تعليمه في 60 ينتج لنا 60 مليون دوره تعليمه لكي
نولد فتره زمنيه مقدارها دقيقه اذا يمكن حساب معامل القسمه prescaler كما يلي
Prescaler =
256 / 60000000 = 234375
اي كل ستين
مليون دوره تعليمه يخرج من Prescaler حوالي 234375نبضه
بقسمه هذا الرقم علي 75 نتج رقم صحيح وهو3125 والرقم 75 نحن فرضناه فقط ليكون ناتج
القسمه رقم صحيح هذا الرقم الذي نتج هو عدد مرات المقاطعه للأنتاج الوقت المطلوب
وهوالدقيقه اما الرقم الذ سوف يوضع داخل التيمر ليبدأالتيمر زيرو من العد من عنده
فينتج من طرح الرقم 75 من 256 فينتج لنا الرقم 181 هذا الرقم هو الذ سوف نضعه في
التايمر ليعد من عنده وبذلك يعد التايمر من 181 ويحدث المقاطعه عند طفحان التايمر
حوالي 3125 لينتج لنا الدقيقه اما لحساب الثانيه فالوضع هنا سوف يكون مختلف حيث ان التايمر زيرو سوف
يعد من الرقم 181 فالسؤال هنا كم مره سوف تحدث المقاطعه لينتج لنا الثانيه النتيجه
ببساطه ان حيث ان كل مليون نبضه تعليمه سوف يخرج prescaler حوالي 3906 نبضه نقوم
بقسمه هذا الرقم عليالرقم 75 سوف ينتج لنا 52 اي بعد 52 مقاطعه سوف يبنج ثانيه
والبرنامج التالي تطورناه بحيث يضئ ليد كل ثانيه اما الاخر فيضئ دقيقه وينطفئ
دقيقه مع ملاحظه هنا شئ مهم جدا اننا غيرنا في نوع المتغيرات التي تعد الدقائق
لأحتوائها علي عدد كبير وهو المتغير mn جعلناه من نوع unsigned int وذلك لانه يحتوي علي
رقم كبير نوعا ما
البرنامج
sbit
LED1 at RB0_bit;
sbit
LED2 at RB1_bit;
unsigned
short sec;
unsigned
int mn;
void
interrupt() {
sec ++;
mn++;
if(sec == 52)
{ LED1 = ~LED1; sec=0;}
if(mn == 3125)
{ LED2 = ~LED2;mn=0; } // Toggle LED every sec
TMR0 = 181; // TMR0
returns to its initial value
INTCON.TMR0IF = 0;
// Bit T0IF is cleared so
that the interrupt could reoccur
}
void
main() {
CMCON
= 0x07 ; //
Disbale comparators
TRISB
= 0b00000000; //
PORTB All Outputs
TRISA
= 0b00100000; //
PORTA All Outputs, Except RA5=MCLR
LED1 = 0; LED2 = 0;
sec = 0; mn = 0;
OPTION_REG = 0x07;
// Prescaler (1:256) is assigned to the timer TMR0
TMR0 = 181; // Timer T0 counts from 39 to 255
INTCON = 0xA0; // Enable interrupt TMR0 and Global Interrupts
do {
}
while(1); //
infinite loop
}
|
مخطط الدائرة الجديده
تطويرالبرنامج(2)
سوف
نطور البرنامج السابق وذلك لعرض عدد مرات المقاطاعات وايضا الثواني وكذلك الدقائق
وعرض ذلك
علي شاشه LCD
مخطط الدائرة الجديده
البرنامج (Software)
sbit LCD_RS at Rb4_bit;
sbit LCD_EN at Rb5_bit;
sbit LCD_D4 at Rb0_bit;
sbit LCD_D5 at Rb1_bit;
sbit LCD_D6 at Rb2_bit;
sbit LCD_D7 at Rb3_bit;
sbit LCD_RS_Direction at TRISb4_bit;
sbit LCD_EN_Direction at TRISb5_bit;
sbit LCD_D4_Direction at TRISb0_bit;
sbit LCD_D5_Direction at TRISb1_bit;
sbit LCD_D6_Direction at TRISb2_bit;
sbit LCD_D7_Direction at TRISb3_bit;
char message0[] = "inter";
char message1[] = " sec";
char message2[] = " min";
char *inter_uput = "00";
char *sec = "00";
char *minut = "00";
unsigned int
count_rput,count_sec,count_minut,sss;
unsigned int mn;
void interrupt() {
count_rput ++; mn++;
if(count_rput == 52) {
count_sec++; count_rput=0;}
if(mn == 3125) {count_minut++; count_rput=0; count_sec=0;mn=0; }
TMR0 = 181;
INTCON.TMR0IF = 0;
}
void main() {
CMCON = 0x07 ;
TRISB = 0b00000000;
TRISA = 0b00100000;
OPTION_REG = 0x07;
TMR0 = 181;
INTCON = 0xA0;
count_rput=0;
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1,1,message0);
Lcd_Out(1,7,message1);
Lcd_Out(1,12,message2);
do {
inter_uput[0]
= (count_rput/10)%10 + 48;
inter_uput[1]
= count_rput%10 + 48;
sec[0] = (count_sec/10)%10 + 48;
sec[1] = count_sec%10 + 48;
minut[0]
= (count_minut/10)%10 + 48;
minut[1]
= count_minut%10 + 48;
Lcd_Out(2,2,inter_uput);
Lcd_Out(2,8,sec);
Lcd_Out(2,14,minut);
} while(1);
}
|
شرح البرنامج
البرنامج سوف يقوم بعمل عداد ليعد عدد مرات المقاطعات ولكن نصفر هذا العداد
كل ثانيه والمتغير المسئول هن هذا العد هو count_rput
وبعد ان يتخطي هذا العداد العدد 52 فسوف
يزيد المتغير count_secالمسئول عن الثواني
بمقدار واحد اي الثواني سوف تزيد بمقدار
وحد بعد 52 مقاطعه ويزيد المتغير count_minut المسئول عن الدقائق بمقدار واحد بعد عدد3125
مقاطعه يتم حسابها عن طريق المتغيرmn حيث يزيد بقدار واحد عند كل مقاطعه مع
ملاحظه اننا نصفر هذا المتغير عندما يحدث 3125مقاطعه اي يمر دقيقه بالضبط ويتم عرض كلا من العداد
المقاطعات والثواني والدقائق من خلال البرنامج
جزاك الله خيرا
ردحذف