عرض مشاركة واحدة
  #31  
قديم 09-22-2011, 06:52 PM
 
فى البداية سوف ننشأ زمن تأخير بقيمة واحد ثانية تقريبا باستخدام موديول المؤقت Timer 0 كمؤقت . الميكروكونترولر يعمل على تردد ساعة المذبذب Fosc = 4MHz لذلك يكون الزمن الدورى للتعليمة هو 1 μs . لتوليد فترة تأخير زمنى قدرها ثانية يجب أن يعد المؤقت مليون 1000000 دورة تعليمة . فإذا استخدمنا معامل القسمة prescaler بالقيمة 256 فإن العدد المطلوب يقل من مليون إلى
1000000/256 = 3906 . والآن إذا حملنا السجل TMR0 بالقيمة المسبقة 39 فإن طفحانه سوف يحدث بعد 256-39 = 217 counts وهكذا تكون عدد مرات الطفحان المطلوبة 3906/217 = 18 . بهذه الإعدادات فإنه بعد 18 مرة طفحان للسجل TMR0 (وفى كل مرة يتم تحميله مسبقا بالقيمة 39 ) ينقضى فترة زمنية قدرها واحد ثانية تقريبا .
البرنامج يوظف هذا التأخير فى عمل وميض لليد .

التعليق على البرنامج :

1- مقدمة (رأس) البرنامج :
/*PIC16F628
1 sec timer using TIMER0
Oscillator @ 4MHz, MCLR Enabled, PWRT Enabled, WDT OFF
*/
2- تعريف الطرف RB0 (المتصل به الليد) باسم يسهل تتبع وفهم البرنامج وهو LED . هذا الطرف هو الخانة صفر من سجل وظائف خاصة وهو المنفذ PORTB لذلك نستخدم التعبير
sbit LED at RB0_bit; " تذكر هذا التعريف" . والإعلان عن متغير العداد .

// Define LED connection

sbit LED at RB0_bit;
unsigned short Num;
3- دالة أو روتين خدمة المقاطعة والتى يتم استدعائها وتنفيذها عند حدوث المقاطعة وتحتوى على :

// Interrupt service routine

void interrupt() {
# عند حدوث المقاطعة يتم تزايد المتغير بواحد Num ++;

Num ++; // Interrupt causes Num to be incremented by 1
# اختبار أو التحقق من شرط if : هل المتغير يساوى 18 ؟ فى البداية بالطبع لا . ولا يحدث شىء ويخرج من جملة if ليجد التحميل المسبق لسجل المؤقت TMR0 بالقيمة المسبقة 39 ويليها تصفير خانة علم المقاطعة للتجهيز لمقاطعة جديدة . وعند كل طفحان تحدث المقاطعة ويتكرر ما سبق حتى يتحقق الشرط Num == 18 أى بعد 18 مرة طفحان أى بعد مرور ثانية . عندئذ يتم تنفيذ جسم شرط if وهو عكس حالة الليد بالتعليمة LED = ~LED; بعد ذلك يتم تحميل السجل TMR0 بالقيمة المسبقة 39 وتصفير خانة علم المقاطعة بالمؤقت صفر ويتكرر العمل .
if(Num == 18) {
LED = ~LED; // Toggle LED every sec
Num = 0;
}
TMR0 = 39; // TMR0 returns to its initial value
INTCON.T0IF = 0; // Bit T0IF is cleared so that the interrupt could reoccur
}
4- بداية الدالة الرئيسية حيث يتم الإعدادات

void main() {
  • إعداد وتهيئة الميكروكونترولر :
# فصل موديول المقارن CCP لاستخدام جميع الأطراف كمداخل / مخارج رقمية .
# إعداد جميع أطراف المنفذ PORTB كمخارج .
# إعداد جميع أطراف المنفذ PORTA كمخارج فيما عدا الطرف RA5 فيعد كمدخل MCLR .

CMCON = 0x07 ; // Disbale comparators
TRISB = 0b00000000; // PORTB All Outputs
TRISA = 0b00100000; // PORTA All Outputs, Except RA5=MCLR
· الحالة الابتدائية : الليد مطفأ وعداد المؤقت بصفر
LED = 0;
Num = 0;
· إعدادات موديول المؤقت Timer 0 والسجل TMR0 :
# فى سجل الخيارات OPTION_REG يتم تخصيص معامل القسمة لموديول المؤقت Timer 0 واختيار معامل القسمة له بالقيمة 256 .
OPTION_REG = 0x07; // Prescaler (1:256) is assigned to the timer TMR0
# تحميل السجل TMR0 بقيمة مسبقة قدرها 39 ليقوم بالعد بدءا منها وحتى 255 حيث يحدث الطفحان والمقاطعة .
TMR0 = 39; // Timer T0 counts from 39 to 255
# فى سجل التحكم فى المقاطعة INTCON : تمكين المقاطعة بسجل المؤقت TMR0 عند طفحانه والتمكين العام للمقاطعات
INTCON = 0xA0; // Enable interrupt TMR0 and Global Interrupts
· الدخول فى حلقى غير منتهية تحتوى على البرنامج المطلوب تنفيذه بينما يعمل المؤقت فى الخلفية من وراء الكواليس .
do {

// You main programs goes here

} while(1); // infinite loop
}
نظام عمل موديول المؤقت Timer 0 كعداد :
__________________
angel4angel4angel4angel4angel4
رد مع اقتباس