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

أدوات الموضوع

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,894
نشاط [ F.Abdelaziz ]
قوة السمعة:332
قديم 23-07-2017, 10:01 PM المشاركة 1   
افتراضي فهم المقاطعات في الميكروكنترولر PIC مع المترجم ميكروسى برو : Twitter FaceBook Google+



فهم المقاطعات في الميكروكنترولر PIC مع المترجم ميكروسى برو :
المقاطعات هي مفهوم قوي في الأنظمة المدمجة من أجل التحكم فى الأحداث التى تقع في بيئة حساسة للوقت . في النظام المدمج النموذجي ، المعالج المدمج (الميكروكونترولر) هو المسؤول عن القيام بأكثر من مهمة واحدة (ولكن يمكن أن يقوم بعمل مهمة واحدة فقط في نفس الوقت ). على سبيل المثال ، دعونا نقول أنه في منظم درجة حرارة (ثرموستات) رقمى مبرمج لغرفة ، حيث يتم تخصيص الميكروكونترولر لمراقبة درجة حرارة الغرفة ، وتحويل المكيف أو سخان لوضع التشغيل ON ووضع الإيقاف OFF ، والتحكم في شاشة LCD ، والاستجابة لأي إعدادات جديدة لدرجة الحرارة من قبل المستخدم . من بين هذه المهام ، الثلاث مهام الأولى تكون غير حرجة للوقت ويتم تنفيذها بشكل مستمر في تسلسل واحدة تلو الآخرى ، داخل الحلقة الرئيسية . ولكن عندما يضغط المستخدم أي زر على لوحة الإعداد ، يجب أن يكون الميكروكونترولر قادرا على قراءته قبل أن يحرر المستخدم الزر. لذلك هذا الحدث يكون حساس (حرج) للوقت ، ويجب على الميكروكونترولر أن يتوقف عن كل ما يقوم به والاستجابة (الرد) على هذا الحدث ذات الأولوية المرتفعة . هذا ممكن من خلال استخدام المقاطعات interrupts . فى هذا الدرس سوف يتم أولا وصف نظام المقاطعة بشكل عام ثم توضيح كيفية التعامل معه في الميكروكونترولر PIC .
وكما ذكر أعلاه ، تشكل المقاطعات الأساس لفصل الأحداث ذات الحساسية للوقت عن الأحداث الأخرى وتنفيذها بطريقة ذات أولوية . المقاطعة تخبر الميكروكونترولر بترك كل ما يقوم به وتنفيذ برنامج آخر (روتين خدمة المقاطعة ISR ) المخزن في مكان محدد مسبقا في ذاكرة البرنامج . طلبات المقاطعة هي أحداث غير متزامنة مما يعني أنه يمكن حدوث طلب المقاطعة في أي وقت أثناء تنفيذ أحد البرامج . ولكن كلما حدث ذلك ، فإن وحدة المعالجة المركزية تنهى التعليمة الحالية وتخزن عنوان التعليمة التالية (عن طريق عداد البرنامج PC ) في ذاكرة المكدس stack بحيث يمكن للبرنامج الحالي من أن يستمر فى التنفيذ من حيث وقف بمجرد انتهاء روتين خدمة المقاطعة . عتدئذ اقفز وحدة المعالجة المركزية إلى موقع ذاكرة برنامج معين (المةقع 0x0004 فى الميكروكونترولر PIC )، حيث يبدأ روتين خدمة المقاطعة ISR . في نهاية روتين خدمة المقاطعة ، تنفيذ تعليمة العودة return تحميل العنوان الموجود في الجزء العلوي من المكدس مرة أخرى في عداد البرنامج ، ويتقدم التنفيذ من نفس النقطة حيث تم مقاطعة المعالج .
الميكروكونترولر لديه عدة مصادر للمقاطعات ، والتي يمكن أن تكون خارجية أو داخلية . مصادر المقاطعة الداخلية الأكثر شيوعا هي المؤقتات Timers وذاكرة EEPROM وموديول ADC والمقارن Comparator . المقاطعات الخارجية تنشأ في الأجهزة الطرفية وتصل إلى متحكم الميكروكونترولر من خلال واحد من أطرافه والمنافذ المرتبطة به.
المقاطعات يمكن أن يتم تمكينها أو تعطيلها بشكل عام globally ، وكذلك فإن كل مصدر مقاطعة يمكن تمكينه أو تعطيله بشكل فردى .
مصادر المقاطعة فى الميكروكونترولر PIC16F877A :



العائلة PIC16F87XA لديها ما يصل الى 15 من مصادر المقاطعة. ويسجل سجل التحكم في المقاطعة INTCON طلبات المقاطعات الفردية في بتات العلم flag bits . هذا السجل به أيضا بتات التمكين enable bits للمقاطعة الفردية والعمومية .
يسمح بت عموم المقاطعات GIE (INTCON<7>) بتمكين جميع المقاطعات (إذا تم تعيينها set) ، أو تعطيلها جميعا (إذا تم مسحه clear ) . عندما يتم تمكين بت عموم المقاطعات GIE ويتم تحديد بت علم المقاطعة فسوف يتم تفعيل المقاطعة على الفور . المقاطعات الفردية يمكن تعطيلها من خلال ما يقابلها من بتات التمكين في السجلات المختلفة. يتم تعيين بت المقاطعة الفردية بغض النظر عن حالة البت GIE . يتم مسح البت GIE عند إعادة تعيين Reset .
تعليمة "العودة من المقاطعة" RETFIE تخرج روتين المقاطعة ، فضلا عن تعيين set البت GIE ، وهو ما يعيد تمكين المقاطعات.
مقاطعة الطرف RB0/INT ، والمقاطعة عند تغيير المنفذ RB ، والمقاطعة نتيجة طفحان (تجاوز) المؤقت TMR0 موجودة بالسجل INTCON .
أعلام المقاطعة الطرفية موجودة فى سجلات الوظائف الخاصة PIR1 , PIR2 ، وبتات تمكين المقاطعة المناظرة موجودة فى سجلات الوظائف الخاصة PIE1 , PIE2 ، وبت تمكين المقاطعة الطرفية موجود فى السجل INTCON .
عندما يتم الاستجابة للمقاطعة ، يتم مسح البت GIE لتعطيل أي مقاطعة أخرى ، يتم دفع عنوان الرجوع الى المكدس ويتم تحميل عداد البرنامج بالعنوان 0004h . يمكن تحديد مصدر أو مصادر المقاطعة عن طريق تقصى بتات علم المقاطعة .
بت أو بتات علم المقاطعة يجب أن يتم مسحها في البرنامج قبل إعادة تمكين المقاطعات لتجنب تكرار المقاطعات .
بالنسبة لأحداث المقاطعة الخارجية ، مثل مقاطعة الطرف INT أو المقاطعة نتيجة تغيير المنفذ PORTB ، يكون زمن استجابة المقاطعة ثلاث أو أربع دورات تعليمة . يعتمد وقت الاستجابة الصحيح على زمن حدوث حدث المقاطعة . زمن الاستجابة هو نفسه لمدة دورة أو دورتى تعليمة .
يتم تحديد set بتات علم المقاطعة بصرف النظر عن حالة البتات PEIE , GIE المقابلة .

بعض مصادر المقاطعة :

المقاطعة الخارجية نتيجة تطبيق نبضة على الطرف RB0/INT :
المقاطعة الخارجية على الطرف RB0/INT هى مقاطعة تعمل بالحافة edge ، يتم اختيار نوع الحافة ، إما حافة صاعدة rising ( بتحديد set البت السادسة INTEDG بالسجل OPTION_REG<6> ) ، أو حافة هابطة ( بمسح clear البت INTEDG ) . عندما تظهر حافة صالحة على الطرف RB0/INT ، يتم تحديد set بت علم المقاطعة الخارجية INTF ، وهى البت الأولى بالسجل INTCON<1> . يمكن تعطيل هذه المقاطعة عن طريق مسح بت تمكينها INTE ، وهى البت الرابعة بالسجل INTCON<4> . بت العلم INTF يجب أن يتم مسحها فى البرنامج ، فى روتين خدمة المقاطعة ، قبل إعادة تمكين هذه المقاطعة . يمكن للمقاطعة الخارجية INT أن توقظ المعالج من النوم إذا كانت البت INTE قد تم تعيينها قبل الذهاب إلى النوم .

مقاطعة المؤقت TMR0 :
حدوث طفحان overflow(FFh → 00h) فى سجل المؤقت TMR0 سوف يحدد set بت العلم TMR0IF ، البت الثانية بالسجل INTCON<2> . يمكن تمكين / تعطيل هذه المقاطعة عن طريق تحديد set / مسح clear بت التمكين TMR0IE ، البت الخامسة بالسجل INTCON<5> .

المقاطعة نتيجة تغيير حالة أطراف المنفذ PORTB :
التغيير فى دخل الأطراف من 4 إلى 7 للمنفذ PORTB<7:4> ، تحدد set بت العلم RBIF وهى البت صفر للسجل INTCON<0> . يمكن تمكين / تعطيل هذه المقاطعة عن طريق تحديد / مسح بت التمكين RBIE ، وهى البت الرابعة للسجل INTCON<4> .



كل من هذه المقاطعات يمكن تمكينها أو تعطيلها بشكل فردي ، ويمكن أن تكون أكثر من مقاطعة واحدة نشطة في نفس الوقت . عند طلب مقاطعة ، ينتهي الميكروكونترولر من تنفيذ التعليمة الحالية، ويخزن قيمة عداد البرنامج في المكدس ، ويقفز إلى الغنوان 0004h في ذاكرة البرنامج ، حيث يقع روتين خدمة المقاطعة . ونظرا لأن جميع مصادر المقاطعة تجعل البرنامج يقفز إلى نفس المكان (0004h) ، فإنه يجب على المبرمج ، عند كتابة روتين خدمة المقاطعة ، أولا معرفة المصدر الذي طلب المقاطعة . ويتم ذلك من خلال قراءة البتات المناسبة في سجلات الوظيفة الخاصة ، INTCON و PIR1 ، المرتبطة بنظام المقاطعة . ويبين الشكل أدناه البتات في سجل التحكم في المقاطعة INTCON .

احصائية الشكر والاعجاب - 1 شكراً, 0 عدم اعجاب, 1 اعجاب
شكراً عبدالله حجازى ( شكر العضو على هذه المشاركة )
اعجاب عبدالله حجازى ( أعجبته المشاركة )
اعلانات

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,894
نشاط [ F.Abdelaziz ]
قوة السمعة:332
قديم 23-07-2017, 10:04 PM المشاركة 2   
افتراضي


تدريب 1 :
الغرض :
دراسة كيفية برمجة المقاطعة الخارجية نتيجة تطبيق نبضة على الطرف RB0/INT .

من أجل تهيئة المقاطعة INT ، يجب أن تتم العمليات التالية:
1- يجب أن يتم تهيئةالطرف RB0 كدخل (وهو الوضع الافتراضى ) .
2- يجب تعيين مصدر المقاطعة لتكون الإشارة إما بحافة هابطة أو حافة صاعدة ، باستخدام البت INTEDG بالسجل OPTION_REG .
3- يجب أن تكون بت علم المقاطعة الخارجية (البت INTF بالسجل INTCON ) ممسوحة (صفر) كحالة ابتدائية .
4- يجب تمكين بت عموم المقاطعات عن طريق تحديد (واحد) البت GIE بالسجل INTCON .
5- يجب تمكين بت المقاطعة الخارجية INT من خلال تحديد (واحد) البت INTE بالسجل INTCON .

الدائرة الكهربية :



يتم توصيل مفتاح ضاغط إلى الطرف RB0 ، هذا المفتاح سوف ينتج مقاطعة عند الضغط عليه . كما يتم توصيل أربع ليدات حمراء إلى الأطراف RC0-RC3 وليد أصفر إلى الطرف RD0 .
البرنامج الرئيسى هو عداد تصاعدى ثنائى 4-bit والذى يتزايد بمعدل واحد ثانية تقريبا . يتم إرسال قيمة الغداد إلى المنفذ PORTC والغرض على الأربع ليدات الحمراء . اليد الصفراء يتم تحويلها ON و OFF عند الضغط على المفتاح .
المفتاح فعال فى الحالة المنخفضة ولذلك يتم برمجة المقاطعة على الحافة الهابطة (تغيير من 5V إلى 0V ) ، من خلال جعل INTEDG = 0 (الحالة الابتدائية بواحد) .
يعتمد روتين خدمة المقاطعة ISR على التطبيق المحدد . ومع ذلك ، تطبق بعض الخطوات على جميع الحالات . على سبيل المثال ، يجب أن يبدأ روتين خدمة المقاطعة بالتحقق من الحدث المحدد الذي تسبب في المقاطعة (إذا تم تمكين أكثر من مقاطعة ) . في هذه الحالة ، يجب فحص البت INTF من السجل INTCON للتحقق من أن مصدر المقاطعة هو من الطرف RB0/INT .
وبالمثل ، يجب أن يتم مسح علم المقاطعة (البتINTF من السجل INTCON ) بواسطة روتين خدمة المقاطعة قبل العودة إلى البرنامج الرئيسي وإلا ستحدث سلسلة لا نهاية لها من المقاطعات . وذلك لأنه عند العودة فإن وحدة المعالجة المركزية سوف تجد علم المقاطعة لا يزال فى حالة تعيين set ويفترض أنها مقاطعة أخرى ويقفز مرة أخرى إلى روتين خدمة المقاطعة .
فى الميكروكونترولر ، يقوم المعالج تلقائيا بمسح بت عموم المقاطعات GIE بالسجل INTCON عندما تحجث مقاطعة . هذا يعنى أنه لا يمكن وقوع مقاطعة فى روتين خدمة المقاطعة ، وإلا تخيل الفوضى التى سوف تحدث ما لم يكن ينبغى هذا الحال .
عندما يقوم المعالج بتنفيذ عبارة الرجوع فى روتين خدمة المقاطعة ، يتم تحديد set البت GIE ويتم تمكين المقاطعات مرة أخرى .
فى هذا التدريب سوف نستخدم المترجم ميكروسى برو . فى هذا المترجم يتم كتابة روتين خدمة المقاطعة مثل أى برنامج فرعى (دالة) آخر لكن مع استخدام الاسم بالكلمة الخاصة (المحجوزة) interrupt . داخل روتين خدمة المقاطعة يتم اختبار بتات الأعلام المناسبة للتعرف على مصدر المقاطعة .
البرنامج :

كود:
/*
Understanding Interrupts
*/
 
sbit LED at RD0_bit;  // Interrupt LED
unsigned short count;
 
// Interrupt service routine
void interrupt(){
 if(INTCON.INTF == 1) LED = ~LED;
 delay_ms(200);   // Key debounce time
 INTCON.INTF = 0;
}
 
void main() {
  TRISB.B0 = 1 ; // RB0 as input 
  TRISC = 0;    // PORTC all outputs
  TRISD = 0 ; // PORTD all outputs
  PORTD = 0 ; 

 INTCON = 0b10010000;   // Set GIEand INTE bits , INTCON.GIE=1; INTCON.INTE=1; 
 OPTION_REG.INTEDG = 0; // External interrupt on falling edge of RB0/INT pin
 count = 0;
 LED = 0;
 PORTC = count;
 do {
  count ++;
  if (count ==16) count =0;
  PORTC = count;
  delay_ms(1000);
 }while (1); // infinite loop  
}
النتيجة :
سوف ترى أن الميكروكونترولر سوف يحافظ على العد من 0 إلى 15 ويلف مرة أخرى من الصفر ويستمر فى ذلك . فى أى وقت تقوم بالضغط على المفتاح الضاغط ، تحدث المقاطعة ، وسوف يستجيب المعالج إليها عن طريق تغيير حالة الليد الأصفر ، بعد ذلك سوف يستأنف مهمة العد .

احصائية الشكر والاعجاب - 2 شكراً, 0 عدم اعجاب, 1 اعجاب
شكراً عبدالله حجازى, عريبى محمود ( شكر العضو على هذه المشاركة )
اعجاب عبدالله حجازى ( أعجبته المشاركة )
اعلانات اضافية ( قم بتسجيل الدخول لاخفائها )
  

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,894
نشاط [ F.Abdelaziz ]
قوة السمعة:332
قديم 23-07-2017, 10:09 PM المشاركة 3   
افتراضي


تدريب 2 :
الدائرة الكهربية :




البرنامج :

كود:
/*
 Etxernal Interrupt (INT- RB0)
 * Description:
     This is a simple interrupt demostration project.
     All LEDs on PORTD will flash utill interrupt occurs (RB0 is pressed).
     Interrupt will set local flag , which will cause Flashing routine to be executed.
  */

bit flag;

void Delay250() {
  Delay_ms(250);
}

void Delay150() {
  Delay_ms(150);
}

void Flash () {            // Flashing rutine
  PORTD.F1 = 1;
  Delay150();
  PORTD.F1 = 0;
  Delay250(); Delay250();
  PORTD.F1 = 1;
  Delay150();
  PORTD.F1 = 0;
  Delay250(); Delay250();
}

void interrupt(){           // Interrupt rutine
  if(INTF_bit == 1 ) {     // Checks Receive Interrupt Flag bit
    flag      = 1;          // Set local interrupt flag
    INTF_bit = 0;          // Clear Interrupt Flag
  }
}

void main() {
  flag   = 0;               // Varialbe initialisation
   TRISB  = 1;               // Set PORT B (only RB0) as input
  TRISD  = 0;               // Set PORT D as output
  PORTD   = 0x00;            // Set all pin on PORT D Low
   INTEDG_bit = 1;          // Set interrupt on rising edge
  INTF_bit  = 0;          // Clear INT0 flag
  INTE_bit  = 1;          // Enable INT0 interrupts
  GIE_bit     = 1;          // Enable GLOBAL interrupts

  while(1) {
    PORTD = 0xFF;            // Set all pin on PORT D High
    Delay250();             // Wait for some time
    PORTD = 0x00;            // Set all pin on PORT D Low
    Delay150();             // Wait for some time
    if(flag) {              // Checks local interrupt flag
      Flash();            // Do something
      flag = 0;             // Reset local interrupt flag
    }
  }
}



تدريب 3 :
الدائرة الكهربية :



البرنامج :

كود:
/*
 * Project name:
     Etxernal Interrupt (RB4:RB7)
  * Description:
     This is a simple interrupt demostration project.
     All LEDs on PORTD will flash utill interrupt occurs.
     Interrupt will set local flag, which will cause Flashing routine to be executed.
     Depending on pressed button (RB4:RB7) different Flashing routine will be executed.
*/


char pressedButton;
bit flag;

void interrupt(){              // Interrupt rutine
  if(RBIF_bit == 1 ) {         // Checks for Receive Interrupt Flag bit
    flag  = 1;                 // Set local interrupt flag
    RBIF_bit = 0;              // Clear Interrupt Flag
    if (PORTB.F7 == 1){        // Checks if the RB7 is pressed
       pressedButton = 7;
    }
    if (PORTB.F6 == 1){        // Checks if the RB6 is pressed
       pressedButton = 6;
    }
    if (PORTB.F5 == 1){        // Checks if the RB5 is pressed
       pressedButton = 5;
    }
    if (PORTB.F4 == 1){        // Checks if the RB4 is pressed
       pressedButton = 4;
    }
  }
}

void Delay250() {
  Delay_ms(250);                // Waits for 250 ms
}

void Delay150() {
  Delay_ms(150);                // Waits for 150 ms
}

void FlashIt(char hexCode){     // Flashes LEDs two times
  PORTD = hexCode;               // Writes hex to to PORTD
  Delay150();                   // Short pause
  PORTD = 0;                     // Clears PORTD
  Delay250(); Delay250();       // Pause
  PORTD = hexCode;               // Writes hex to to PORTD second time
  Delay150();                   // Short pause
  PORTD = 0;                     // Clears PORTD
  Delay250(); Delay250();       // Pause
}


void main() {                  
  flag          = 0;           // Varialbe initialisation
  pressedButton = 0;
  
  TRISB  = 0xFF;               // Set PORT B as input
  TRISD  = 0;                  // Set PORT D as output
  PORTD   = 0x00;               // Set all pin on PORT D Low
  
  RBIE_bit  = 1;               // Enable Port B Interrupt-On-Change
   RBIF_bit  = 0;               // Clear IOC flag
  GIE_bit   = 1;               // Enable GLOBAL interrupts


  while(1) {
    PORTD = 0xFF;               // Set all pin on PORT D High
    Delay250();                // Wait for some time
    PORTD = 0x00;               // Set all pin on PORT D Low
    Delay150();                // Wait for some time

    if(flag) {
      switch(pressedButton) {  // Depending on value(button pressed), calls FleshIt function with different argument
      case 4:
           FlashIt(0x03);
           pressedButton = 0;
      break;
      case 5:
           FlashIt(0x0C);
           pressedButton = 0;
      break;
      case 6:
           FlashIt(0x30);
           pressedButton = 0;
      break;
      case 7:
           FlashIt(0xC0);
           pressedButton = 0;
      break;
      default:
           FlashIt(0xAA);       // Just in case
      break;
      }
      flag = 0;                 // Reset flag variable
    }
  }
}

احصائية الشكر والاعجاب - 2 شكراً, 0 عدم اعجاب, 1 اعجاب
شكراً عبدالله حجازى, عريبى محمود ( شكر العضو على هذه المشاركة )
اعجاب عبدالله حجازى ( أعجبته المشاركة )

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,894
نشاط [ F.Abdelaziz ]
قوة السمعة:332
قديم 23-07-2017, 10:13 PM المشاركة 4   
افتراضي


تدريب 4 :
الدائرة الكهربية :




البرنامج :

كود:
/*
 * Project name:
     Peripheral Interrupt (Interrupt while reciving data over UART)
 
 * Description:
     This is a simple interrupt demostration project.
     uC will send some data for connectivty test.
     Received data will be saved in buffer using interrut.
     Last recived character will be diplayed on portD.
*/

char rxbuff[20];                    // Buffer variable for storing data sent from master
char rxidx;                         // Counter for data writen in buffer

void interrupt() {                  // Interrupt rutine
   if(RCIF_bit == 1) {             // Checks for Receive Interrupt Flag bit
     rxbuff[rxidx] = UART1_Read();   // Storing read data
     rxidx++;                       // Incresing counter of read data
     if(rxidx >= 20)                // Checks if data is larger than buffer
       rxidx = 0;                   // Reset counter
   }
}

void main() {
  rxidx  = 0;                       // Initialisation of variable
  
  TRISD  = 0;                       // Configure PORTD as output

  UART1_Init(19200);                // Initialize UART module at 19200 bps
  Delay_ms(100);                    // Wait for UART module to stabilize

  UART1_Write_Text("Start");        // Send text
  UART1_Write(13);                  // ASCII carriage return
  UART1_Write(10);                  // ASCII line feed (new line)

  PORTD = 0xFF;                      // Set all pin on PORT D High
  Delay_ms(100);                    // Wait for some time
  PORTD = 0x00;                      // Set all pin on PORT D Low

  RCIE_bit = 1;                    // turn ON interrupt on UART1 receive
  RCIF_bit = 0;                    // Clear interrupt flag
  PEIE_bit  = 1;                    // Enable peripheral interrupts
  GIE_bit   = 1;                    // Enable GLOBAL interrupts

  while(1) {
    if (rxidx == 0) {               // Nothing is read, or buffer overflows
       PORTD = rxbuff[rxidx];        // Do something(Show first char that will be overwriten)
    }
    else {
       PORTD = rxbuff[rxidx-1];      // Show binary value of the read character on PORT D
    }
  }
}

احصائية الشكر والاعجاب - 1 شكراً, 0 عدم اعجاب, 1 اعجاب
شكراً عبدالله حجازى ( شكر العضو على هذه المشاركة )
اعجاب عبدالله حجازى ( أعجبته المشاركة )

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,894
نشاط [ F.Abdelaziz ]
قوة السمعة:332
قديم 23-07-2017, 10:18 PM المشاركة 5   
افتراضي


تدريب 5 : التعامل مع مقاطعات متعددة
المقاطعات هى أحداث مجدولة والتى تجعل الميكروكونترولر PIC "يعلق" برنامجه القائم على تنفيذه ويقوم بتشغيل جزء من برنامج (برنامج فرعى يسمى روتين المقاطعة interrupt routine) مقترن بحدث .
عند اكتمال روتين المقاطعة يستمر PIC فى تنفيذ سريان البرنامج من عند نفس النقطة التى كان قد علق عندها التنفيذ.
مصادر المقاطعة تختلف تبعا لنوع الميكروكونترولر . على سبيل المثال الميكروكونترولر PIC 16F877A له 15 مصدر للمقاطعة مثل :
• المقاطعة بالمؤقت Timer0 عند حدوث طفحان بالمؤقت .
• المقاطعة عن تغيير حافة النبضة الخارجية على الطرف RB0 (تعرف بالمقاطعة الخارجية) .
• المقاطعة عند وصول البيانات التسلسلية خلال الوحدة USART .
• المقاطعة بالمحول من تناظرى لرقمى ADC عند انتهاء التحويل .
وغيرها من المقاطعات .
مترجم الميكروسى برو يتضمن دالة سابقة التعريف من أجل تنفيذ المقاطعة ، هذه الدالة هى "دالة أو روتين المقاطعة" وهى بالصيغة التالية :
void interrupt (void);
يجب إعلان هذه الدالة قبل الدالة الرئيسية .
عند حدوث مقاطعة يتم استدعاء "دالة المقاطعة" تلقائيا عن طريق البرنامج ، داخل هذه الدالة يجب تحديد ما هى المقاطعات التى يتم بدؤها وأعلام (معلمات - علامات) flags كل مقاطعة .
لإعداد المقاطعات يجب تفعيل البتات المناظرة بسجلات المقاطعة . فى الميكروكونترولر PIC16F877A ، على سبيل المثال ، سجلات المقاطعة هى : INTCON, PIR1, PIR2, PIE1 , PIE2 . الشكل التالى يبين هذه السجلات يالميكروكونترولر PIC 16F877A :



لتنفيذ المقاطعات يجب اتباع الخطوات المناسبة للإعداد مع مرعاة ما يلى :
• أولا يتم تفعيل المقاطعات المطلوب استخدامها عن طريق بت التمكين IEالمناسب مثل :
TMR0IE, INTE, RCIE وغيرها .
• يجب عدم تمكين أعلام المقاطعات مثل :
TMR0IF, INTF, RCIF وغيرها .
• يجب تمكين مقاطعات الطرفيات عندما يتطلب ذلك ، على سبيل المثال المقاطعات التابعة للسجلات :
PIE1 و PIE2.
• وأخيرا يتم تحديد set بت تمكين عموم المقاطعات : GIE .


المثال التالى سوف يستخدم فى : المقاطعة باستقبال الاتصال التسلسلى ، والمقاطعة بالمؤقت Timer 0 ، والمقاطعة الخارجية . لهذا الهدف يمكنك مراقبة وتحليل كود المصدر للبرنامج التالى :

كود:
//1-declaration interrupt function.
void interrupt ( void )
{
	//A-Declaration of variables used in interrupt function.
	char Data;
	//B-Evaluates whether the interrupt is triggered by Timer 0, TMR0IF
	if( INTCON.F2==1 )
	{
		//It complements the bit value RB1.
		if(PORTB.F1==1)
		PORTB.F1=0;
		else
		PORTB.F1=1;
		// Turned off Timer 0 Flag.
		INTCON.F2=0;
	}
	//C-Evaluates whether the external interrupt is triggered.
	// INTF
	if( INTCON.F1==1 )
	{
		//It complements the bit value RB2.
		if(PORTB.F2==1)
		PORTB.F2=0;
		else
		PORTB.F2=1;
		//It turns off the external interrupt flag.
		INTCON.F1=0;
	}
	//D-Evaluates whether the interruption triggered by serial reception.
	if( PIR1.F5 ==1)
	{
		//It reads the input data.
		Data = UART1_Read();
		//Confirmation information is sent.
		UART1_Write_Text("Input data: ");
		//It sends the data received.
		UART1_Write(Data);
		UART1_Write(13); //ASCII code is sent enter.
		UART1_Write(10); //and sends carriage return code.
		//It reception apparatus for serial flag.
		PIR1.F5 = 0;
	}
}

void main( void )
{
	//Ports are configured.
	TRISB = 0b00000001;
	PORTB = 0;
	//Activates the serial receive interrupt.
	PIE1 = 0b00100000;
	//Other interrupt sources are disabled .
	PIE2 = 0;
	//Turn off interrupt flags.
	PIR2 = 0;
	PIR1 = 0;
	//Setting the Timer 0 to 65.535 m Sec
	OPTION_REG=0b11000111;
	//Configuring the serial port at 9600 bps.
	UART1_Init(9600);
	//Global interrupts are enabled,
	//for Timer 0, and external.
	INTCON = 0b11110000;
	while(1) //Infinite Loop.
	{
	}
}
لمحاكاة هذا البرنامج ببرنامج إيزيس يتم جلب الأجهزة التالية :
16F877A, RES, BUTTON, LED-RED والوحدة الطرفية التخيلية والأوسليسكوب .
بعد تشغيل المحاكاة يجب التفاعل مع الوحدة الطرفية لإرسال بيانات , بالمفتاح الضاغط يجب أن تشاهد حالة الليد وخرج الأوسليسكوب وعرض شكل الموجة المربعة يتغير كل 65.535 msec , تبعا للمؤقت Timer 0 .
الدائرة الكهربية :




احصائية الشكر والاعجاب - 2 شكراً, 0 عدم اعجاب, 2 اعجاب
شكراً عبدالله حجازى, سعيد قادر ( شكر العضو على هذه المشاركة )
اعجاب عبدالله حجازى, سعيد قادر ( أعجبته المشاركة )
إضافة رد

العلامات المرجعية

«     الموضوع السابق       الموضوع التالي    »
أدوات الموضوع

الانتقال السريع إلى


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

Powered by vBulletin® Version 3.8.6, Copyright ©2000 - 2025