 |
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
|
|
نشاط [ F.Abdelaziz ]
قوة السمعة:
|
|
28-07-2017, 11:25 PM
المشاركة 10
|
|
تدريب على المقاطعة باستخدام المؤقتات
الغرض
• استخدام المؤقتات TMR0, TMR1 , TMR2 .
• استخدام المقاطعات .
ربما لاحظت وجود عيب عند تنفيذ التأخير عند استخدام الحلقات.
في مثل تلك الحالة يكون الميكروكونترولر 'أسير' ولا يفعل شيئا. ببساطة ينتظر لحين مرور بعض الوقت.
هذا الوقت الضائع ترفا غير مقبول لذلك يجب تطبيق بعض الطرق الأخرى .
هل تتذكر موضوع المؤقتات ؟
هل تتذكر موضوع المقاطعات ؟
هذا التدريب يصنع رابط بينهما بطريقة عملية .
الدائرة الكهربية :

فكرة البرنامج :
• مطلوب توفير تأخير طويل بما يكفى لملاحظة التغيرات على المنفذ . يستخدم لذلك الموقت TMR0 مع تخصيص "معامل القسمة " prescaler لهذا الغرض.
• يتم إنشاء مقاطعة عند كل حدوث طفحان overflow بسجل المؤقت TMR0 فيتم تنفيذ روتين المقاطعة وفى كل مرة يقوم روتين المقاطعة تلقائيا بتزايد المتغير "cnt" بواحد .
• عندما تصل القيمة الموجودة بهذا المتغير إلى 400 يتم تزايد المنفذ port B بواحد وتظهر النتيجة على شكل إضاءة ليدات .
يتم تنفيذ الإجراء بأكمله من 'وراء الكواليس، مما يمكن الميكروكونترولر بعمل شىء آخر .
النتيجة :
إضاءة الليدات الثمانية المتصلة بالمنفذ PORT B بشكل يمثل الأرقام من 1 إلى 255 بالنظام الثنائى أى من 00000001 إلى 11111111 .

حساب زمن المقاطعة :
كود:
(4/8MHz) * prescaler * (255-96)
0.5 * 32 * 159 = 2544us = 2.544ms
2.544 * 400 times = 1 sec
البرنامج :
كود:
unsigned cnt; // Define variable cnt
void interrupt() {
cnt++; // Interrupt causes cnt to be incremented by 1
TMR0 = 96; // Timer TMR0 is returned its initial value
INTCON = 0x20; // Bit T0IE is set, bit T0IF is cleared
}
void main() {
OPTION_REG = 0x84; // Prescaler is assigned to timer TMR0
TRISB = 0; // All port B pins are configured as outputs
PORTB = 0x0; // Reset port B
TMR0 = 96; // Timer T0 counts from 96 to 255
INTCON = 0xA0; // Enable interrupt TMR0
cnt = 0; // Variable cnt is assigned a 0
do { // Endless loop
if (cnt == 400) { // Increment port B after 400 interrupts
PORTB = PORTB++; // Increment number on port B by 1
cnt = 0; // Reset variable cnt
}
} while(1);
}
المقاطعة باستخدام المؤقت TMR1 :
فى هذه الحالة يتم تمكين المقاطعة بعد حدوث طفحان فى المؤقت TMR1 والمكون من السجلين
(TMR1H, TMR1L). مزيج من تغيرات الخانات فى المنفذ PORT B يختلف عن البرنامج السابق حيث يتم إضاءة الأربعة خانات الأولى ثم بعد فترة التأخير تنطفأ ويتم إضاءة الأربع خانات الأخيرة وبعد فترة التأخير تتكرر العملية .

حسابات زمن المقاطعة :
كود:
TMR1H = 0x80; // Set initial value for timer TMR1
TMR1L = 0x00; // TMR1 = 32768
(4/8MHz) * prescaler * (65535 – 32768 )
0.5 * 1 * 32767 = 16383.5 us = 16.384 ms
16.384 ms * 76 times = 1.2 sec
البرنامج :
كود:
unsigned short cnt; // Define variable cnt
void interrupt() {
cnt++ ; // Interrupt causes cnt to be incremented by 1
PIR1.TMR1IF = 0; // Reset bit TMR1IF
TMR1H = 0x80; // TMR1H and TMR1L timer registers are returned
TMR1L = 0x00; // their initial values
}
void main() {
PORTB = 0xF0; // Initial value of port B bits
TRISB = 0; // Port B pins are configured as outputs
T1CON = 1; // Set timer TMR1 , prescaler 1:1
PIR1.TMR1IF = 0; // Reset bit TMR1IF
TMR1H = 0x80; // Set initial value for timer TMR1
TMR1L = 0x00;
PIE1.TMR1IE = 1; // Enable interrupt on overflow
cnt = 0; // Reset variable cnt
INTCON = 0xC0; // Enable interrupt (bits GIE and PEIE)
do { // Endless loop
if (cnt == 76) { // Change port B state after 76 interrupts
PORTB = ~PORTB; // Number in port B is inverted
cnt = 0; // Reset variable cnt
}
} while (1);
}
المقاطعة باستخدام المؤقت TMR2
• فى هذه الحالة تحدث المقاطعة بعد حدوث طفحان للمؤقت TMR2 .
• يتم إنشاء دالة جديدة تسمى Replace والتى لا تنتمى للغة السى وتستخدم فى عكس حالة أطراف المنفذ .
النتيجة إضاءة الليدات الفردية والانتظار لفترة ثم العكس أى إضاءة الليدات الزوجية والانتظار لفترة ثم تكرار العملية .

حسابات زمن المقاطعة :
كود:
(4/Fosc) * prescaler * postscaler * PR2
(4/8MHz) * 16 * 16 * 255 = 32640 us = 32.640 ms
32.640 * 30 times = 1 sec
البرنامج :
كود:
unsigned short cnt; // Define variable cnt
void Replace() {
PORTB = ~PORTB; // Define new function ‘Replace’
} // Function inverts port state
void interrupt() {
if (PIR1.TMR2IF) { // If bit TMR2IF = 1,
cnt++ ; // Increment variable cnt by 1
PIR1.TMR2IF = 0;// Reset bit and
TMR2 = 0; // reset register TMR2
}
}
// main
void main() {
cnt = 0; // Reset variable cnt
PORTB = 0b10101010; // Logic state on port B pins
TRISB = 0; // All port B pins are configured as outputs
T2CON = 0xFF; // Set timer2, prescaler=16, postscaler=16,TMR2ON
TMR2 = 0; // Initial value of timer register TMR2
PIE1.TMR2IE = 1; // Enable interrupt
INTCON = 0xC0; // Set bits GIE and PEIE
while (1) { // Endless loop
if (cnt > 30) { // Change PORTB after more than 30 interrupts
Replace(); // Function Replace inverts the port B state
cnt = 0; // Reset variable cnt
}
}
}
|