السلام عليكم,
قمت بإنشاء درس بسيط لإستعمال الـtimer0 مع عائلة pic18 لأنني مثال له في المنتدى
<بالمناسبة انا لست خبيرا في المؤقتات قد تكون معلوماتي النظرية غير صحيحة ولكن عمليا قد تكون صحيحة>
في هذا الدرس سأستعمل pic18f4550 نظرا لشهرته وتردد الكريستال 4mhz
في هذا الدرس سنقوم بجعل الـled يضيء كل ثانية وذالك بإستخدام المؤقت timer0 والمقاطعات(interrupts) في وضع 8-bit
كيفية عمل الـtimer0 وهي عند حدوث الطفحان(overflow) يتم تنفيذ/استدعاء الكود الموجود داخل الدالة interrupt
---------------------------------------------
بالنسبة للدرس المسجلات(registers) المستخدمة:-
TMR0L:هذا المسجل نقوم بوضع قيمة له على حسب معادلة معينة(سنناقشها معا)
INTCON:مسؤول عن بعض المقاطعات انظر الصورة

T0CON:يقوم بالتحكم في الـtimer0 انظر الصورة
بما ان مدة التأخير ثانية واحدة كبيرة نسبيا فإننا سنقوم بجعل المقاطعة تحدث كل 1000us أي 1ms ومن ثم نقوم بوضع عداد يعد إلى 1000
لأن الثانية =1000 ميلي ثانية في حال وصل العداد إلى 1000 نقوم بتصفير العداد ونقوم بتبديل(toggle) قيمة الbit السابع من المنفذ B اي نعكس قيمته الحالية.
لحساب قيمة المسجل tmr0l لتأخير 1000 ميكرو ثانية يجب علينا الأخذ في الإعتبار الطول الموجي و الـprescaler

هذه المعطيات:-
time=1000us
clockperiod=1/4 mhz=0.25us
prescaler=32
الأن نقوم بتعويض القيم في المعادلة وسيكون ناتج العملية الحسابية بعد التقريب هو 225
قيمة الـprescaler تعتمد على المسجل T0CON كما شاهدت في الرسم يمكنك تغيرها عن طريق تغير قيمتها في المسجل T0CON
لكنني لن أتطرق إليها الأن لأني أريد أن يكون الدرس أبسط ما يمكن
الهيكل العام للبرنامج:-
كود:
void interrupt(){
}
void main()
{
}
البرنامج:-
سنقوم بتعريف متغير ونسميه count
داخل main():-
نقوم بتصفير قيمة المتغير(count)
نقوم بجعل المنفذ B كخرج
نقوم بتصفير المنفذ B
نقوم بوضع القيمة 225 داخل المسجل TMR0L
نقوم بوضع القيمة 196 داخل المسجل T0CON
نقوم بوضع القيمة 160 داخل المسجل INTCON
أخيرا نقوم بوضع جملة تكرار إلا مالا نهاية
الكود:-
كود:
void main()
{
count=0;
trisb=0;
portb=0;
TMR0L = 225;
T0CON = 196;
INTCON = 160;
while(1){}
}
بالنسبة للدالة interrupt لن أقوم بشرح كل شيء لوضوح الكود عدا أخر سطرين
نقوم بإعادة تحميل المسجلTMR0L بالقيمة 225
ونقوم بتصفير قيمة العلم الخاص بالمقاطعة وإعادة تفعيل مقاطعاته وذلك من خلال وضع القيمة 32 في المسجل INTCON
الكود:-
كود:
void interrupt(){
count++;
if(count==500){
count=0;
portb.f7=!portb.f7;
}
TMR0L = 225;
INTCON=32;
}
ملاحظة: عدلت قيمة العداد إلى 500 لكي يعطينا high كل ثانية
لأنه عندما كان 1000 كان يأخذ ثانية low وثانية high أي ثانيتين
الكود كاملا:-
كود:
int count;
void interrupt(){
count++;
if(count==500){
count=0;
portb.f7=!portb.f7;
}
TMR0L = 225;
INTCON=32;
}
void main()
{
count=0;
trisb=0;
portb=0;
TMR0L = 225;
T0CON = 196;
INTCON = 160;
while(1){} //loop forever
}
في النهاية أتمنى أن يكون الدرس سهل الفهم وبسيط وكذلك مفيد