اخواني الكرام هل يمكن لنا ان نتحكم في زمن تشغيل اللد و اطفائه عن طريق التايمر ؟؟و ليس عن طريق الديليه ... انا اعرف ان اتحكم بنفس الزمن يعني تشغيل ثانيه و اطفاء ثانيه ... و لكن اريد ان اقوم بتشغيل اللد خمس ثواني و اطفائه عشر ثواني عن طريق التايمر .. مع مثال و شرح عليه اذا سمحتم و دمتم..
|
1-يمكن استخدام التايمر لتوليد نبضات دقيقة
و لتنفيذ ما تريد تضيف له عدادا أو أكثر لعد تلك النبضات كما ستلاحظ في المثال المرافق.
وللتحكم في العداد وإجباره على التوقف عند قيمة معينة ممكن تستخدم جملة شرطية مثل جملة if.
2- في الميكروسي يمكن تحويل متغير إلى عداد بطريقة بسيطة :
مثال : هذا متغير اخترت له هذا الاسم: counter
يمكن تحويل هذا المتغير الى عداد بهذه الطريقة في الكتابة :
;++counter
وهي في نفس الوقت تعليمة العد .
3- الآن كيف نستفيد من خدمات برنامج حاسب التايمر ؟
هذا مثال لتوليد نبضات من التايمر 1 بقيمة 100ms:

البيك الذي اخترته Pic16F628A
- إذن اخترت عائلة 16F بأعلى الصفحة.
- اخترت كريستالة : 4Mhz فهي الأكثر انتشارا لكن ممكن تختار غيرها مما هو متاح.
- اخترت التايمر1
- حددت قيمة النبضة المطلوبة وهي 100ms
- تأكدت من أن البرنامج مفعل على الميكروسي في اسفل الصفحة.
- حصلت على الكود الذي يظهر جانب منه في الصورة.
هو هنا كاملا:
كود:
//Timer1
//Prescaler 1:2; TMR1 Preload = 15536; Actual Interrupt Time : 100 ms
//Place/Copy this part in declaration section
void InitTimer1(){
T1CON = 0x11;
TMR1IF_bit = 0;
TMR1H = 0x3C;
TMR1L = 0xB0;
TMR1IE_bit = 1;
INTCON = 0xC0;
}
void Interrupt(){
if (TMR1IF_bit){
TMR1IF_bit = 0;
TMR1H = 0x3C;
TMR1L = 0xB0;
//Enter your code here
}
}
في الصفحة فقرتين بالأخضر ليستا من الكود هما توضيحات فقط.
الفقرة الاولى :
//Timer1
//Prescaler 1:2; TMR1 Preload = 15536; Actual Interrupt Time : 100 ms
//Place/Copy this part in declaration section
توضح نوع التايمر و قيم المقسم Prescaler والمقسم Preload
وتوجه إلى مكان وضع هذا الكود.
والاهم العبارة التي تشير الى قيمة النبضة التي سنشتغل عليها وهي:
Actual Interrupt Time : 100 ms
الفقرة الثانية:
//Enter your code here
توجهنا إلى المكان الذي نضع فيه الكود الذي سنكتب للاستفادة من كود المقاطعة.
و هو هذا الكود البسيط ل 5 تواني تشغيل الليد و 10 إطفاء :
كود:
///
ms_counter++;
if (ms_counter == 10)
{
ms_counter = 0;
s_counter ++;
}
if (s_counter == 5)
{
portb.b0 = 0;
}
if (s_counter == 15)
{
s_counter = 0;
portb.b0 = 1;
}
///
ويتضمن متغيرا سميته ms_counter وحولته إلى عداد يعد نبضات التايمر1 ذات القيمة 100ميلي تانية.
بهذه التعليمة:
;++ms_counter
وبما اني أريد الحصول على 1 تانية
وأن 1 تانية = 100 ميلي تانية * 10 ،
يجب أن يعد لي ++ms_counter النبضات ذات القيمة 100ms عشر مرات ويتوقف .
ولكي يتوقف استخدمت جملة if الاولى :
كود:
if (ms_counter == 10)
{
ms_counter = 0;
s_counter ++;
}
وفيها قمت بتصفيره حتى يكون مستعدا للعد مرة أخرى للحصول على مزيد من التواني.
وضمن نفس الجملة الشرطية شغلت عدادا جديدا بنفس الطريقة وسميته s_counter ليعد لي تلك التواني .
جملة if الثانية ستراقب عداد التواني s_counter ولما يصل الى 5 كما طلبت يجعل الخرج Portb.b0=0:
كود:
if (s_counter == 5)
{
portb.b0 = 0;
}
للاشارة Portb.b0 منذ بداية عمل البرنامج يساوي 1 ، يعني عليه 5 فولت
جملة if الاخيرة سترصد متى يصل عداد التواني s_counter الى 15 لتقوم بجعل Portb.b0=1 يعني عليه جهد 5 فولت من جديد .
و ايضا تصفير هذا العداد عداد التواني s_counter استعدادا لدورة أخرى.
علما بأن 15s=10s+5s
كود:
if (s_counter == 15)
{
s_counter = 0;
portb.b0 = 1;
}
ملحوظة هامة :
يجب وضع تعليمة المناداة على دالة تهيئة مقاطعة التايمر في المكان المضبوط.
هي هنا مكتوبة بالاحمر للتوضيح وفي مكانها المخصص لها:
كود:
void main()
{
cmcon = 7;
trisb = 0; portb.b0 = 1;
InitTimer1();
while (1)
{
}
}
بدون ذلك السطر لن يعمل كود المقاطعة .
معلومة لا يشير لها الحاسب ..
وهنا الكود الكامل لو تحب تجربته أو الاستفسار حوله:
كود:
unsigned short ms_counter =0;
unsigned short s_counter =0;
//Timer1
//Prescaler 1:2; TMR1 Preload = 15536; Actual Interrupt Time : 100 ms
///// Crystal:4Mhz.
//Place/Copy this part in declaration section
void InitTimer1(){
T1CON = 0x11;
TMR1IF_bit = 0;
TMR1H = 0x3C;
TMR1L = 0xB0;
TMR1IE_bit = 1;
INTCON = 0xC0;
}
void Interrupt(){
if (TMR1IF_bit){
TMR1IF_bit = 0;
TMR1H = 0x3C;
TMR1L = 0xB0;
// Enter your code here
///
ms_counter++;
if (ms_counter == 10)
{
ms_counter = 0;
s_counter ++;
}
if (s_counter == 5)
{
portb.b0 = 0;
}
if (s_counter == 15)
{
s_counter = 0;
portb.b0 = 1;
}
///
}
}
void main()
{
cmcon = 7;
trisb = 0; portb.b0 = 1;
InitTimer1();
while (1)
{
}
}