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

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

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,894
نشاط [ F.Abdelaziz ]
قوة السمعة:332
قديم 28-02-2013, 11:34 PM المشاركة 1   
افتراضي سهولة استخدام المقاطعات مع المترجم CCS-PIC-C : Twitter FaceBook Google+



سهولة استخدام المقاطعات مع المترجم CCS-PIC-C :
المقاطعة هى مجرد , استثناء أو تغيير فى سريان أو "المقاطعة" فى عمل البرنامج نتيجة لمصدر أجهزة hardware خارجى أو داخلى .
المقاطعة , فى حقيقة الأمر هى "استدعاء دالة" يتولد بالأجهزة . والنتيجة هى أن المقاطعة سوف تتسبب بتوقف pause سريان تنفيذ البرنامج بينما يتم تنفيذ دالة المقاطعة , والتى تسمى روتين خدمة المقاطعة ISR . بعد انتهاء روتين خدمة المقاطعة مباشرة , سوف يتم أستأناف resume سريان البرنامج , ليستمر من حيث تمت مقاطعته .
تتوفر مصادر كثيرة للمقاطعة فى الميكروكونترولر PIC . كلما كبر الميكروكونترولر PIC , كلما كثرت المصادر المتاحة .
لإنشاء روتين خدمة مقاطعة ISR , الدالة التى تستدعى عن طريق نظام المقاطعة , يتم إعلانها عن طريق استخدام التوجيه #int_xxx. التوجيه #int_xxx يحدد أن الدالة التى تليه يجب أن تستدعى حينما يتم إطلاق المقاطعة "xxx" .

إسلوب برمجة المقاطعة مع المترجم CCS-PICC :
العناصر اللازمة :
علينا أولا النظر فى العناصر اللازمة للتعامل مع المقاطعات .
سوف تحتاج إلى :
· تمكين المقاطعات فى البرنامج بالدالة ‘enable_interrupts(level)’ . يتم ذلك على مستويين .
· المستوى الأول هو المستوى "العمومى" 'globale' , فكر فى هذا المستوى مثل مفتاح القدرة العمومى (الرئيسى) لمقاطعاتك بدون النظر لأى مقاطعات مفردة يمكن أن تعمل .
· المستوى الثانى هو المقاطعة الفردية وهى التى تلى التوجيه ‘int_xxxx’ . مع استمرار التفكير فى تمثيل مفتاح القدرة , يمكنك التفكير فى كل من المقاطعات المفردة مثل مفتاح التحويل والذى يحدد حالة البرنامج .
· لاحظ أنه يمكنك أيضا تعطيل المقاطعات فى البرنامج إذا كنت بحاجة إلى تنفيذ كود بدون المقاطعة , يمكن عمل ذلك بالدالة ‘disable_interrupts(level)’, تعطيل المستوى العمومى ‘global’ يترك المقاطعات الفردية فعالة .

الآن نحن بحاجة لمعرفة كيفية إعلان (تعريف) روتين خدمة المقاطعة ISR .
مع المترجم CCS-PICC يكون الأمر بسيط حقا , يمكنك استخدام توجيه قبل المعالج #int_xxxx حيث ‘ int_xxxx’ المقاطعة الفردية التى تستخدمها , تليها دالة معالجة المقاطعة . وهذه هى بساطة تعامل المترجم , فأنت لا تحتاج إلى حفظ واستعادة البتات, ومسح الأعلام , أو أى من الأشياء الأخرى التى قد تفعلها فى لغة الأسمبلى .
بعد هذه الجولة حول جميع العناصر المطلوبة من أجل المقاطعات , لنلقى نظرة على أمثلة لإشارة مقاطعة خارجية .
المقاطعة نتيجة تغير حالة أطراف الميكروكونترولر PIC16F877A RB (RB4-RB7)

اعلانات

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,894
نشاط [ F.Abdelaziz ]
قوة السمعة:332
قديم 28-02-2013, 11:37 PM المشاركة 2   
افتراضي


المقاطعة نتيجة تغير حالة أطراف الميكروكونترولر PIC16F877A RB (RB4-RB7)
كيف يمكن أن تستخدم المقاطعة RB للكشف عن مفتاح ضاغط (زر) button مضغوط ؟
سوف تحدث المقاطعة RB عندما يكون هناك أى تغيير(دخل أو خرج) على الأطراف B4-B7 للمنفذ PORTB . هناك مقاطعة واحدة ولن يخبرك الميكروكونترولر PIC عن أى طرف قد تغير ! يجب على المبرمج تحديد التغيرعلى أساس قيمة سابقة معروفة للمنفذ . علاوة على ذلك , فإن مفتاح واحد قد يسبب مقاطعات عدة بسبب الارتدادات bounce فى المفتاح . لذلك فسوف تحتاح إلى طريقة برمجية لعلاج الارتدادات داخليا (برمجيا) ( أو خارجيا عن طريق الأجهزة hardware) .
الصيغة العامة :

كود:
byte previous_b; // global variable (byte=unsigned int8) #int_rb //# INT_RB => Port B any change on RB4-RB7 rb_isr() { // Interrupt source => followed by ISR function byte changes, port_b; // local variables port_b=input_b(); // input_b() => read port B input function changes = previous_b ^ port_b; // locate pins changed level (old xor new) previous_b = port_b; // take a current reading and save it for next RB int if (bit_test(changes,4)&& !bit_test(previous_b,4)){ do something 4} //b4 went low if (bit_test(changes,5)&& bit_test (previous_b,5)){do something 5} //b5 went high if (bit_test(changes,6)&& bit_test(previous_b,6)){do something 6} //b4 went high if (bit_test(changes,7)&& !bit_test (previous_b,7)){do something 7} //b5 went low delay_ms (20); // debounce }
التأخير delay = ms (20) هى الوسيلة البسيطة لعلاج ارتداد المفتاح . بشكل عام , سوف لا ترغب فى البقاء فى روتين خدمة المقاطعة لمدة 20ms للسماح بعلاج ارتداد المفتاح . الحل الأكثر فائدة هو وضع مؤقت فى بداية المقاطعة والانتظار حتى يحدث فيضان overflow للمؤقت . لا يتم معالجة المزيد من التغيرات على الطرف .
مثال :
التحكم فى توصيل on وفصل 2 ليد عن طريق 2 مفتاح ضاغط كل على حدة :
الدائرة الكهربية :

البرنامج :


كود:
#include "16F877A.h" #use delay (clock=4M) // 4MHz crystal #fuses XT, NOWDT, NOPUT, NOPROTECT // interrupt from RB (RB4 to RB7) byte old_portb=0; // global var; assume initially zero #int_rb void rb4to7_isr() { // check what pin changed status byte i, change; delay_ms(20); // debouncing the switches i=input_B(); // input_B =>Inputs an entire byte from a port change= i ^ old_portb;// locate pins changed level (old xor new) old_portb=i; // save as old for next interrupt if (bit_test(change,4)==1) // b4 went high output_toggle(PIN_D0); //Toggles the high/low state of the specified pin //toggle RD0 if (bit_test(change,7)==1) // b7 went high output_toggle(PIN_D1); // toggle RD1 } void main() { port_b_pullups(0); // disable enable_interrupts(int_rb); enable_interrupts(global); while(1) { } }

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

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


المقاطعة الداخلية بالمؤقتات :
عادة ينفذ المعالج الدقيق كود البرنامج بشكل متتابع . على الرغم من ذلك , يوجد حالات عندها يتطلب من المعالج الدقيق "تعليق التنفيذ مؤقتا " لحين التصدى لحالة غير غادية . يدث ذلك فى الميكروكونترولر PIC كنتيجة لطلبات المقاطعة interrupt .
تنشأ المقاطعة عند حدوث حالة معينة . هذه الحالة قد تكون طفحان overflow للمؤقت / العداد , أو تغير فى حالة خط دخل , أو استقبال بايت على المنفذ التسلسلى , أو تمام التحويل من تناظرى لرقمى .
سوف نركز فقط على المقاطعات المتولدة عند الفترات الزمنية المنتظمة عن طريق طفحان المؤقت العداد . فى البداية يتم قسمة تردد الساعة على "4" , ثم بعد ذلك يتم قسمتها مرة أخرى على معامل مقياس مسبق prescaler ثنائى ( بالنسب 1,2,4,….256) . وفى النهاية تطبق على دخل عداد ثنائى بطول يعتمد على المؤقت المستخدم ( على سبيل المثال "16-bit" ) . عندما يمتلىء هذا العداد يحدث "طفح" overflow ( كل 65536 نبضة تطبق على الدخل) فيولد مقاطعة. نتيجة لذلك يعطى معدل المقاطعة بالعلاقة التالية :


كود:
Interrupt rate = clock frequency / ( 4 x 65536 x prescaler )

يمكن استخدام المقاطعات المرتبطة بالتوقيت لتنفيذ مهام عند فترات زمنية منتظمة فى حين يتم تعليق المهمة الرئيسية فى الخلفية .

شكل البرنامج الكامل كما يلى :
كود:
////////////////Comments /////////////////////// // Title : Interrupts //Author : Eng.F.Abdelaziz // Date : 1-3-2013 ////////////// Setups ////////////////////////////
#include <16F877.h>#fuses HS,NOWDT,NOPROTECT,NOLVP#use delay(clock=4M)
//////////////// Definitions //////////////////////////// #define led pin_b0 /////////// Interrupts //////////////////////// #INT_TIMER0 void timer0_isr( ) { output_high(led) ; delay_ms(500) ; output_low(led) ; delay_ms(500) ; } ///////////// Main ////////////////////// void main ( ) { ///////////////////// Enable Interrupt levels ////////////////// setup_counters(RTCC_INTERNAL,RTCC_DIV_256);// setup timer 0 enable_interrupts(INT_TIMER0) ; enable_interrupts(GLOBAL) ; //////////////////////////////////// Main task ////////////////////////////////////// for( ; ; ) { } ////////////////////////////////////////////////////////////// }

يتم مقاطعة المهمة الرئيسية ( وهى حلقة for غير منتهية لغرض التبسيط ) عند فترات زمنية منتظمة , مهمة المقاطعة وميض ليد متصل بالطرف B0 .
التوجيه #INT_TIMER0 : يعرف الدالة التالية له كدالة مقاطعة , وسوف تستدعى فى كل مرة يتم فيها طلب المقاطعة بالمؤقت , كما يلى :

كود:
#INT_TIMER0 void timer0_isr( )
كل مقاطعة بالمؤقت تسبب تنفيذ الدالة التالية لمرة واحدة :

كود:
setup_counters(RTCC_INTERNAL,RTCC_DIV_1);// setup timer 0
هذه العبارة تحدد معامل القسمة prescaler للمؤقت . فى هذه الحالة يتم تحديد المعامل بالقيمة "1" , ولكن القيمة يمكن أن تكون فى المدى من "1"RTCC_DIV_1) ) إلى "256"(RTCC_DIV_256) بتزايد ثنائى .
العبارة :

كود:
enable_interrupts(INT_TIMER0) ;

تحدد المستوى المعطى للمقاطعة , فى هذه الحالة المستوى يناظر مقاطعات المؤقت TIMER0 .
العبارة :

كود:
enable_interrupts(GLOBAL) ;

تسمح للمقاطعات التى تم تمكينها سابقا بأن تصبع فعالة ومن ثم تسمح بتواد طلبات المقاطعة بالمؤقت .


yassinema1992
:: مهندس ::
تاريخ التسجيل: Dec 2012
المشاركات: 35
نشاط [ yassinema1992 ]
قوة السمعة:0
قديم 02-03-2013, 12:06 PM المشاركة 4   
افتراضي


السلام عليكم
شرح جيد في انتضار الجزء الخاص بالمقاطعة ب التايمر 1 ccp capture


الصورة الرمزية Semmoor
Semmoor
:: مهندس متميز ::
تاريخ التسجيل: Oct 2011
المشاركات: 300
نشاط [ Semmoor ]
قوة السمعة:0
قديم 04-03-2013, 05:17 PM المشاركة 5   
افتراضي


السلام عليكم ممكن اخي عبدالعزيز رابط لتحميل كتاب

Embedded C Programming and the Microchip PIC


الصورة الرمزية Abdw9
Abdw9
:: عضو فضي ::
تاريخ التسجيل: Nov 2011
الدولة: السودان
المشاركات: 557
نشاط [ Abdw9 ]
قوة السمعة:77
قديم 05-03-2013, 08:56 AM المشاركة 6   
افتراضي


اخي الكريم واستاذي المبدع دوما والمتألق مهندس F.Abdelaziz لك كل الشكر وكل التقدير على الشرح الجميييييييييييييييل وفقك الله وسدد خطاك
ومتابع معك باهتمام وفي انتظار الجزئية الثانية

إضافة رد

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

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

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


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

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