قسم الميكروكنترولر والروبوت ودوائر الاتصال بالحاسب الالي قسم المتحكمات الـ microcontroller و المعالجات microprocessor و التحكم الرقمي بالكمبيوتر CNC والانظمة الآلية والروبوت Robots

   

أبو كريم555
:: مهندس ::
تاريخ التسجيل: May 2016
المشاركات: 30
نشاط [ أبو كريم555 ]
قوة السمعة:
قديم 26-01-2018, 01:26 PM المشاركة 9   
افتراضي



السلام عليكم
أريد أن أسأل كيف يمكن حساب الوقت بين تحقق الشرط و عدم تحققه بمساعدة التايمر ؟

اعلانات

A-M-S
:: مهندس جيد ::
تاريخ التسجيل: May 2014
المشاركات: 242
نشاط [ A-M-S ]
قوة السمعة:
قديم 28-01-2018, 04:16 PM المشاركة 10   
افتراضي


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)
        {


        }
}

السلام عليكم .... اخي بارك الله فيك و في امثالك و جعله في ميزان حسناتك .. واضح ان حضرتك بذلت مجهود كبير في ايصال المعلومه و الحمد لله وصلت نوعا ما .... انا كنت اعمل على البرنامج تايمر كالكيولاتير و بالاخص على TIMER0 و لكن لم اكن افهم تعليماته جيدا و ان شاء الله اني الان فهمت و الفضل يرجع لله تعالى و لحضرتك .... سأجرب الكود و اوافيك بالنتيجه .....اخي هل هناك فرق بين التايمر واحد و التايمر زيرو من حيث البرمجه؟؟ يعني هل بامكاني اضع التايمر زيرو في البرنامج بدل التايمر 1 و اعمل على نفس الكود السابق؟؟

اعلانات اضافية ( قم بتسجيل الدخول لاخفائها )

محمد إلياس
:: مهندس جيد ::
تاريخ التسجيل: Jan 2017
المشاركات: 229
نشاط [ محمد إلياس ]
قوة السمعة:
قديم 28-01-2018, 06:41 PM المشاركة 11   
افتراضي


السلام عليكم .... اخي بارك الله فيك و في امثالك و جعله في ميزان حسناتك .. واضح ان حضرتك بذلت مجهود كبير في ايصال المعلومه و الحمد لله وصلت نوعا ما .... انا كنت اعمل على البرنامج تايمر كالكيولاتير و بالاخص على TIMER0 و لكن لم اكن افهم تعليماته جيدا و ان شاء الله اني الان فهمت و الفضل يرجع لله تعالى و لحضرتك .... سأجرب الكود و اوافيك بالنتيجه .....اخي هل هناك فرق بين التايمر واحد و التايمر زيرو من حيث البرمجه؟؟ يعني هل بامكاني اضع التايمر زيرو في البرنامج بدل التايمر 1 و اعمل على نفس الكود السابق؟؟
السلام عليكم
العفو أخي بارك الله فيك.
أخي قبل أن أقوم بالرد السابق عملت المثال أولا بالتايمر 0 ثم بالتايمر 1 ولاحظت
أن التايمر 1 أكثر دقة .
ربما لان التايمر 0 مسجل ب8 بت فقط بينما التايمر 1 مسجل ب16 بت

تفضل نفس المثال لكن بالتايمر0:
كود:
// Pic16F628A - osc:4Mhz
 
unsigned int ms_counter =0;
unsigned int s_counter =0;

//Timer0
//Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms
 //Place/Copy this part in declaration section
 
void InitTimer0(){
  OPTION_REG     = 0x81; //or: 0b10000001;
  TMR0           = 6;
  INTCON         = 0xA0; //or: 0b10100000;
}
 
void Interrupt(){
  if (TMR0IF_bit){ 
    TMR0IF_bit         = 0;
    TMR0               = 6;
        
    //Enter your code here:
    
       ///////////////////////////////////////:
        ms_counter++;

        if (ms_counter == 1000)
        {
         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.b0 = 0; portb.b0 = 1;
        InitTimer0();
                
        while (1)
        {


        }
}
لاحظ أن زمن المقاطعة هذه المرة 1ms
وبما أن 1 تانية يساوي 1000 ميلي تانية يجب على العداد ms_counter أن يعد 1000 مرة في كل دورة.

ملفات المثالين :

ملفات التايمر 0 + ملفات التايمر1:
https://up.top4top.net/downloadf-758jjl171-rar.html



المحاكاة ببروتوس 8.5
أرجو أن يفيدك ما سبق
وإذا كانت لديك استفسارات تفضل..


التعديل الأخير تم بواسطة : محمد إلياس بتاريخ 28-01-2018 الساعة 10:14 PM

محمد إلياس
:: مهندس جيد ::
تاريخ التسجيل: Jan 2017
المشاركات: 229
نشاط [ محمد إلياس ]
قوة السمعة:
قديم 28-01-2018, 08:05 PM المشاركة 12   
افتراضي


السلام عليكم
العفو أخي بارك الله فيك.
أخي قبل أن أقوم بالرد السابق عملت المثال أولا بالتايمر 0 ثم بالتايمر 1 ولاحظت
أن التايمر 1 أكثر دقة .
ربما لان التايمر 0 مسجل ب8 بت فقط بينما التايمر 1 مسجل ب16 بت


تفضل نفس المثال لكن بالتايمر0:
كود:
// Pic16F628A - osc:4Mhz
 
unsigned int ms_counter =0;
unsigned int s_counter =0;

//Timer0
//Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms
 //Place/Copy this part in declaration section
 
void InitTimer0(){
  OPTION_REG     = 0x81; //or: 0b10000001;
  TMR0           = 6;
  INTCON         = 0xA0; //or: 0b10100000;
}
 
void Interrupt(){
  if (TMR0IF_bit){ 
    TMR0IF_bit         = 0;
    TMR0               = 6;
        
    //Enter your code here:
    
       ///////////////////////////////////////:
        ms_counter++;

        if (ms_counter == 1000)
        {
         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.b0 = 0; portb.b0 = 1;
        InitTimer0();
                
        while (1)
        {


        }
}
لاحظ أن زمن المقاطعة هذه المرة 1ms
وبما أن 1 تانية يساوي 1000 ميلي تانية يجب على العداد ms_counter أن يعد 1000 مرة في كل دورة.

ملفات المثالين :

ملفات التايمر 0 + ملفات التايمر1:
https://up.top4top.net/downloadf-758jjl171-rar.html

المحاكاة ببروتوس 8.5
أرجو أن يفيدك ما سبق
وإذا كانت لديك استفسارات تفضل..
متابعة لما سبق:
1- بخصوص الطريقة والخطوات في برنامج حاسب التايمر فهي نفسها لجميع التايمرات .
الاختلاف طبعا في التعليمات فكل تايمر يشتغل بمسجلات مختلفة عن النوع الآخر.
التايمر0 مثلا يشغل المسجلين الشهيرين option_reg و intcon
البرنامج وضع أمام كل واحد منهما القيمة بالسادس عشري هكّذا :
كود:
OPTION_REG     = 0x81; 

  INTCON         = 0xA0;
لاحظ أخي أني وضعت لك أمام القيمة بالسادس عشري ما يقابلها بالتنائي في مكان التعاليق طبعا.
وهذا حتى تتمكن ، لو كنت تحب تتعمق في البحث عن أصل الأشياء ، من معاينة المسجلين في الداتا شيت وتتعرف على كل bit منهما وما هو دوره عندما يكون 0 وما دوره عندما يكون 1.
وخاصة بالنسبة للمسحل OPTION_REG وبالأخص البتات الثلاث الاولى (ابتداء من اليمين) والبت الرابع .


2- خطوات استخدام التيمر0:
1*
إعدادات برنامج الحاسب:

2*
كود المقاطعة الذي أنتجه البرنامج هو:
كود:
//Timer0
//Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms
 
//Place/Copy this part in declaration section
void InitTimer0(){
  OPTION_REG	 = 0x81;
  TMR0		 = 6;
  INTCON	 = 0xA0;
}
 
void Interrupt(){
  if (TMR0IF_bit){ 
    TMR0IF_bit	 = 0;
    TMR0		 = 6;
    //Enter your code here
  }
}
بمذبذب 4 ميغاهرتز كان الناتج هو :مقطعة كل 1 ميللي تانية
يعني للحصول عل 1 تانية لازم عداد يحسب 1000 مرة (1s = 1000ms).
في المثال العداد المقصود سبق أن وضعت له اسما هو ms_counter.
3*
الان بعد حصولي على كود المقاطعة ، أذهب الى صفحة المشروع بالميكروسي.
تظهر بهذه الكتابة وهي الدالة الرئيسية لأي مشروع:
كود:
void main() {

}
فوق هذه الدالة أي في مكان التعريفات بأعلى الصفحة
أضع المتغيرين المستخدمين :
كود:
unsigned int ms_counter =0;
unsigned int s_counter =0;


void main() {

}
4*
ما بين تعريف المتغيرين والدالة الرئيسية أنسخ كود المقاطعة الذي حصلت عليه من البرنامج:
ستبدو صفحة الميكروسي هكذا:
كود:
unsigned int ms_counter =0;
unsigned int s_counter =0;

//Timer0
//Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms

//Place/Copy this part in declaration section
void InitTimer0(){
  OPTION_REG	 = 0x81;
  TMR0		 = 6;
  INTCON	 = 0xA0;
}

void Interrupt(){
  if (TMR0IF_bit){
    TMR0IF_bit	 = 0;
    TMR0		 = 6;
    //Enter your code here
  }
}



void main() {

}
5*
الآن لنتذكر الكود البسيط لحساب الميلي تواني وحساب التواني و 15 تانية الذي سبق لي كتابته :
كود:
///////////////////////////////////////:
        ms_counter++;

        if (ms_counter == 1000)
        {
         ms_counter = 0;
         s_counter ++;
        }
        
        if (s_counter == 5)
        {
         portb.b0 = 0;
        }

        if (s_counter == 15)
        {
         s_counter = 0;
         portb.b0 = 1;
        }

      ///////////////////////////////////////.
في صفحة المشروع بالميكروسي يجب وضعه تحت هذا السطر:
//Enter your code here
الى هنا تظهر الصفحة هكذا:
كود:
unsigned int ms_counter =0;
unsigned int s_counter =0;

//Timer0
//Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms
 //Place/Copy this part in declaration section
 
void InitTimer0(){
  OPTION_REG     = 0x81; //or: 0b10000001;
  TMR0           = 6;
  INTCON         = 0xA0; //or: 0b10100000;
}
 
void Interrupt(){
  if (TMR0IF_bit){ 
    TMR0IF_bit         = 0;
    TMR0               = 6;
        
    //Enter your code here:
    
       ///////////////////////////////////////:
        ms_counter++;

        if (ms_counter == 1000)
        {
         ms_counter = 0;
         s_counter ++;
        }
        
        if (s_counter == 5)
        {
         portb.b0 = 0;
        }

        if (s_counter == 15)
        {
         s_counter = 0;
         portb.b0 = 1;
        }

      ///////////////////////////////////////.
  } 
 
 }
     
   
void main()
{
        
}
6* يبقى فقط إدراج تعليمات معروفة توضع داخل الدالة الرئيسية
مع التنبيه إلى تعليمة النداء على دالة التايمر0 وهي التعليمة:
كود:
InitTimer0();
فيصبح الكود كاملا هكذا:
كود:
// Pic16F628A - osc:4Mhz
 
unsigned int ms_counter =0;
unsigned int s_counter =0;

//Timer0
//Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms
 //Place/Copy this part in declaration section
 
void InitTimer0(){
  OPTION_REG     = 0x81; //or: 0b10000001;
  TMR0           = 6;
  INTCON         = 0xA0; //or: 0b10100000;
}
 
void Interrupt(){
  if (TMR0IF_bit){ 
    TMR0IF_bit         = 0;
    TMR0               = 6;
        
    //Enter your code here:
    
       ///////////////////////////////////////:
        ms_counter++;

        if (ms_counter == 1000)
        {
         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.b0 = 0; portb.b0 = 1;
        InitTimer0();
                
        while (1)
        {


        }
}
أو بعد تخليصه من الزوائد:
كود:
// Pic16F628A - osc:4Mhz
 
unsigned int ms_counter =0;
unsigned int s_counter =0;

//Timer0
void InitTimer0(){
  OPTION_REG     = 0x81; //or: 0b10000001;
  TMR0           = 6;
  INTCON         = 0xA0; //or: 0b10100000;
}
 
void Interrupt(){
  if (TMR0IF_bit){ 
    TMR0IF_bit         = 0;
    TMR0               = 6;
        
   
        ms_counter++;

        if (ms_counter == 1000)
        {
         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.b0 = 0; portb.b0 = 1;
        InitTimer0();
                
        while (1)
        {


        }
}


التعديل الأخير تم بواسطة : محمد إلياس بتاريخ 28-01-2018 الساعة 10:15 PM

A-M-S
:: مهندس جيد ::
تاريخ التسجيل: May 2014
المشاركات: 242
نشاط [ A-M-S ]
قوة السمعة:
قديم 29-01-2018, 05:04 PM المشاركة 13   
افتراضي


متابعة لما سبق:
1- بخصوص الطريقة والخطوات في برنامج حاسب التايمر فهي نفسها لجميع التايمرات .
الاختلاف طبعا في التعليمات فكل تايمر يشتغل بمسجلات مختلفة عن النوع الآخر.
التايمر0 مثلا يشغل المسجلين الشهيرين option_reg و intcon
البرنامج وضع أمام كل واحد منهما القيمة بالسادس عشري هكّذا :
كود:
OPTION_REG     = 0x81; 

  INTCON         = 0xA0;
لاحظ أخي أني وضعت لك أمام القيمة بالسادس عشري ما يقابلها بالتنائي في مكان التعاليق طبعا.
وهذا حتى تتمكن ، لو كنت تحب تتعمق في البحث عن أصل الأشياء ، من معاينة المسجلين في الداتا شيت وتتعرف على كل bit منهما وما هو دوره عندما يكون 0 وما دوره عندما يكون 1.
وخاصة بالنسبة للمسحل OPTION_REG وبالأخص البتات الثلاث الاولى (ابتداء من اليمين) والبت الرابع .


2- خطوات استخدام التيمر0:
1*
إعدادات برنامج الحاسب:

2*
كود المقاطعة الذي أنتجه البرنامج هو:
كود:
//Timer0
//Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms
 
//Place/Copy this part in declaration section
void InitTimer0(){
  OPTION_REG	 = 0x81;
  TMR0		 = 6;
  INTCON	 = 0xA0;
}
 
void Interrupt(){
  if (TMR0IF_bit){ 
    TMR0IF_bit	 = 0;
    TMR0		 = 6;
    //Enter your code here
  }
}
بمذبذب 4 ميغاهرتز كان الناتج هو :مقطعة كل 1 ميللي تانية
يعني للحصول عل 1 تانية لازم عداد يحسب 1000 مرة (1s = 1000ms).
في المثال العداد المقصود سبق أن وضعت له اسما هو ms_counter.
3*
الان بعد حصولي على كود المقاطعة ، أذهب الى صفحة المشروع بالميكروسي.
تظهر بهذه الكتابة وهي الدالة الرئيسية لأي مشروع:
كود:
void main() {

}
فوق هذه الدالة أي في مكان التعريفات بأعلى الصفحة
أضع المتغيرين المستخدمين :
كود:
unsigned int ms_counter =0;
unsigned int s_counter =0;


void main() {

}
4*
ما بين تعريف المتغيرين والدالة الرئيسية أنسخ كود المقاطعة الذي حصلت عليه من البرنامج:
ستبدو صفحة الميكروسي هكذا:
كود:
unsigned int ms_counter =0;
unsigned int s_counter =0;

//Timer0
//Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms

//Place/Copy this part in declaration section
void InitTimer0(){
  OPTION_REG	 = 0x81;
  TMR0		 = 6;
  INTCON	 = 0xA0;
}

void Interrupt(){
  if (TMR0IF_bit){
    TMR0IF_bit	 = 0;
    TMR0		 = 6;
    //Enter your code here
  }
}



void main() {

}
5*
الآن لنتذكر الكود البسيط لحساب الميلي تواني وحساب التواني و 15 تانية الذي سبق لي كتابته :
كود:
///////////////////////////////////////:
        ms_counter++;

        if (ms_counter == 1000)
        {
         ms_counter = 0;
         s_counter ++;
        }
        
        if (s_counter == 5)
        {
         portb.b0 = 0;
        }

        if (s_counter == 15)
        {
         s_counter = 0;
         portb.b0 = 1;
        }

      ///////////////////////////////////////.
في صفحة المشروع بالميكروسي يجب وضعه تحت هذا السطر:
//Enter your code here
الى هنا تظهر الصفحة هكذا:
كود:
unsigned int ms_counter =0;
unsigned int s_counter =0;

//Timer0
//Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms
 //Place/Copy this part in declaration section
 
void InitTimer0(){
  OPTION_REG     = 0x81; //or: 0b10000001;
  TMR0           = 6;
  INTCON         = 0xA0; //or: 0b10100000;
}
 
void Interrupt(){
  if (TMR0IF_bit){ 
    TMR0IF_bit         = 0;
    TMR0               = 6;
        
    //Enter your code here:
    
       ///////////////////////////////////////:
        ms_counter++;

        if (ms_counter == 1000)
        {
         ms_counter = 0;
         s_counter ++;
        }
        
        if (s_counter == 5)
        {
         portb.b0 = 0;
        }

        if (s_counter == 15)
        {
         s_counter = 0;
         portb.b0 = 1;
        }

      ///////////////////////////////////////.
  } 
 
 }
     
   
void main()
{
        
}
6* يبقى فقط إدراج تعليمات معروفة توضع داخل الدالة الرئيسية
مع التنبيه إلى تعليمة النداء على دالة التايمر0 وهي التعليمة:
كود:
InitTimer0();
فيصبح الكود كاملا هكذا:
كود:
// Pic16F628A - osc:4Mhz
 
unsigned int ms_counter =0;
unsigned int s_counter =0;

//Timer0
//Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms
 //Place/Copy this part in declaration section
 
void InitTimer0(){
  OPTION_REG     = 0x81; //or: 0b10000001;
  TMR0           = 6;
  INTCON         = 0xA0; //or: 0b10100000;
}
 
void Interrupt(){
  if (TMR0IF_bit){ 
    TMR0IF_bit         = 0;
    TMR0               = 6;
        
    //Enter your code here:
    
       ///////////////////////////////////////:
        ms_counter++;

        if (ms_counter == 1000)
        {
         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.b0 = 0; portb.b0 = 1;
        InitTimer0();
                
        while (1)
        {


        }
}
أو بعد تخليصه من الزوائد:
كود:
// Pic16F628A - osc:4Mhz
 
unsigned int ms_counter =0;
unsigned int s_counter =0;

//Timer0
void InitTimer0(){
  OPTION_REG     = 0x81; //or: 0b10000001;
  TMR0           = 6;
  INTCON         = 0xA0; //or: 0b10100000;
}
 
void Interrupt(){
  if (TMR0IF_bit){ 
    TMR0IF_bit         = 0;
    TMR0               = 6;
        
   
        ms_counter++;

        if (ms_counter == 1000)
        {
         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.b0 = 0; portb.b0 = 1;
        InitTimer0();
                
        while (1)
        {


        }
}
تسلم الايادي اخي الكريم
انا قمت بتجربة الكود السابق (تايمر واحد ) و النتيجه كانت ممتازه و الحمد لله ... غير انه اشتغل اربع ليدات و ليس ليد واحد و لكن قمت بمعالجة الموضوع حيث وضعت portb=0b00000001; بدل portb.f0=1; و الحمد لله كله تمام .. و لكن ما حيرني انني حاولت ان اقوم بتغيير الزمن الذي و ضعته حضرتك بنفس الطريقه و لكن الامر لم يفلح ....قمت بتغيير زمن التشغيل من 10 ثواني الى 20 و امر الاطفاء الى 30 و قمت بجمعهن في if الاخيره و لكن لم يعمل التايم بنفس الوقت الذي طلبته .. هل هناك أليه معينه مثلا ؟؟


محمد إلياس
:: مهندس جيد ::
تاريخ التسجيل: Jan 2017
المشاركات: 229
نشاط [ محمد إلياس ]
قوة السمعة:
قديم 29-01-2018, 07:14 PM المشاركة 14   
افتراضي


أخي فكرة البرنامج هي
-- منذ البداية (يعني في الدالة الرئيسية) Portb.b0=1
يعني الليد يضيء.
-- العداد s_counter يبدا في العد حتى 5 تواني فيطفئ الليد يعني Portb.b0=0
وبذلك يكون زمن التشغيل 5 تواني.
-- يستمر s_counter في العد الى أن يصل إلى 15 فيشغل الليد من جديد.
وبذلك يكون زمن الاطفاء 10 تواني.
لماذا 15 ؟
لان s_counter لما وصل الى 5 تواني لم نقم بتصفيره بل تركناه يكمل العد .
أي أنك عند كتابة قيمة زمن الاطفاء المطلوبة تضيف عليها عدد زمن التشغيل.

لاحظ المحاكاة الجديدة للملفات السابقة بعدما أدخلت عليها تعديل يسمح برؤية زمن التشغيل 5 تواني وزمن الاطفاء 10 تواني :

التايمر0 :
https://up.top4top.net/downloadf-759ggqny1-rar.html
التايمر1 (أفضل دقة من التايمر0):
https://up.top4top.net/downloadf-759di9wy2-rar.html


فلو تحب التعديل الذي طلبت فسيكون على s_counter في ال if الاولى وال if
الثانية.
هكذا :

علما أن هذه مجرد طريقة ..
ممكن تفكر في غيرها وتستخدم مثلا متغير يحسب زمن التشغيل ومتغير آخر مختلف يحسب لك زمن الاطفاء
تسميهما مثلا:
led_on
led_off
أو غير ذلك.
وللتحكم في المتغيرات تستخدم جمل if كما في المثال
وتقوم يتصفير المتغيرات في اللحظة المناسبة.
أرجو لك التوفيق..


التعديل الأخير تم بواسطة : محمد إلياس بتاريخ 29-01-2018 الساعة 10:23 PM


الساعة معتمدة بتوقيت جرينتش +3 الساعة الآن: 07:11 AM
موقع القرية الالكترونية غير مسؤول عن أي اتفاق تجاري أو تعاوني بين الأعضاء
فعلى كل شخص تحمل مسئولية نفسه إتجاه مايقوم به من بيع وشراء وإتفاق وأعطاء معلومات موقعه
التعليقات المنشورة لا تعبر عن رأي موقع القرية الالكترونية ولايتحمل الموقع أي مسؤولية قانونية حيال ذلك (ويتحمل كاتبها مسؤولية النشر)