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

   

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




قياس درجة حرارة باستخدام الحساس LM35 وعرضها على 4 وحدات سفن سيجمنت

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










البرنامج :



كود:
/*
 * Project name: Multiplexing_7-Segment 4 UNITS
     MCU:             PIC16F877A , ADC , LM35
     Oscillator:      HS, 8.0000 MHz
     SW:              mikroC PRO
*/
#define Digit1 PORTD.B0 // THOUTHAND
#define Digit2 PORTD.B1 // HUNDRED
#define Digit3 PORTD.B2 // TENS
#define Digit4 PORTD.B3 // ONES

unsigned char Display (unsigned char digit)
  {
    unsigned char pattern;
    unsigned char  SEGMENT_MAP[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
    pattern =  SEGMENT_MAP[digit] ;  //The pattern to return
    return (pattern);
  }

void main() {
  unsigned char DD1,DD2, DD3,DD4 ;
  unsigned int result; //
  float scale ;
  char num ;
  ADCON1= 0;           //
  TRISA.B0=1; // AN0 INPUT
  TRISD = 0;            // Configure PORTD as outputs , COMMON CATHODES
  TRISB = 0;            // Configure PORTB as outputs ,7 SEGMENT DATA PORT

Digit1 = 0;            //Disable digit 1
Digit2 = 0;            //Disable digit 2
Digit3 = 0;            //Disable digit 3
Digit4 = 0;            //Disable digit 4


  while(1){
  result=ADC_Read(0);  // Read analog value from channel 0
  scale = result * (5000.0/1023.0); // input analog voltage
  scale = scale /10.0 ; // input temp inc for LM35
  num = scale ;
 ///////////
       DD1 = num / 1000;       //Extract DD1 from result >>THOUTHAND
       PORTB = Display(DD1);    //Display the DD1
       Digit1 = 1;             //Enable digit 1
       Delay_Ms(10);            //a short 10ms delay
       Digit1 = 0;             //Disable digit 1
 /////////
       DD2 = (num/100) % 10;        // DD2 digit >>>HUNDRED
       PORTB = Display(DD2);    //Display the DD3
       Digit2 = 1;             //Enable digit 2
       Delay_Ms(10);            //a short 10ms delay
       Digit2 = 0;             //Disable digit 2
   ////////////
   DD3 = (num/10) % 10;       //Extract DD3 from result >>TENS
       PORTB = Display(DD3);    //Display the DD3
       Digit3 = 1;             //Enable digit 3
       Delay_Ms(10);            //a short 10ms delay
       Digit3 = 0;             //Disable digit 3
   /////////
   DD4 = num % 10;       //Extract DD4 from result >>ONES
       PORTB = Display(DD4);    //Display the DD4
       Digit4 = 1;             //Enable digit 4
       Delay_Ms(10);            //a short 10ms delay
       Digit4 = 0;             //Disable digit 4
    }
}

اعلانات

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




تطوير للتدريب السابق بوضع حرف :"C" للإشارة إلى الدرجات المئوية .

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



البرنامج :



كود:
/*
 * Project name: Multiplexing_7-Segment 4 UNITS
     MCU:             PIC16F877A , ADC , LM35 MOD
     Oscillator:      HS, 8.0000 MHz
     SW:              mikroC PRO
*/
#define Digit1 PORTD.B0 //  DIGIT 1 FROM LEFT , THOUTHAND
#define Digit2 PORTD.B1 // DIGIT 2 FROM LEFT , HUNDRED
#define Digit3 PORTD.B2 // DIGIT 3 FROM LEFT , TENS
#define Digit4 PORTD.B3 // DIGIT 4 FROM LEFT ,  ONES

unsigned char Display (unsigned char digit)
  {
    unsigned char pattern;
    unsigned char  SEGMENT_MAP[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
    pattern =  SEGMENT_MAP[digit] ;  //The pattern to return
    return (pattern);
  }

void main() {
  unsigned char DD1,DD2, DD3,DD4 ;
  unsigned int ADC_result; //
  float scale ;
  unsigned int num ;
  ADCON1= 0;           //
  TRISA.B0=1; // AN0 INPUT
  TRISD = 0;            // Configure PORTD as outputs , COMMON CATHODES
  TRISB = 0;            // Configure PORTB as outputs ,7 SEGMENT DATA PORT

Digit1 = 0;            //Disable digit 1
Digit2 = 0;            //Disable digit 2
Digit3 = 0;            //Disable digit 3
Digit4 = 0;            //Disable digit 4


  while(1){
  ADC_result=ADC_Read(0);  // Read analog value from channel 0
  scale = ADC_result * (5000.0/1023.0); // input analog voltage
  num = scale /10.0 ; // input temp inc for LM35
 ///////////
       DD1 = num / 100;       //Extract DD1 from ADC_result >>THOUTHAND
       PORTB = Display(DD1);    //Display the DD1
       Digit1 = 1;             //Enable digit 1
       Delay_Ms(10);            //a short 10ms delay
       Digit1 = 0;             //Disable digit 1
 /////////
       DD2 = (num/10) % 10;        // DD2 digit >>>HUNDRED
       PORTB = Display(DD2);    //Display the DD3
       Digit2 = 1;             //Enable digit 2
       Delay_Ms(10);            //a short 10ms delay
       Digit2 = 0;             //Disable digit 2
   ////////////
   DD3 = num % 10;       //Extract DD3 from ADC_result >>TENS
       PORTB = Display(DD3);    //Display the DD3
       Digit3 = 1;             //Enable digit 3
       Delay_Ms(10);            //a short 10ms delay
       Digit3 = 0;             //Disable digit 3
   /////////
   //DD4 = num % 10;       //Extract DD4 from ADC_result >>ONES
       PORTB = 0x39;    //Display C CHARACTER
       Digit4 = 1;             //Enable digit 4
       Delay_Ms(10);            //a short 10ms delay
       Digit4 = 0;             //Disable digit 4
    }
}

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

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




إزالة حرف "C" واستخدام خانة الآحاد لبيان كسر الآحاد مع عرض النقطة العشرية على وحدة السفن سيجمنت :

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




البرنامج :



كود:
/*
 * Project name: Multiplexing_7-Segment 4 UNITS
     MCU:             PIC16F877A , ADC , LM35 MOD
     Oscillator:      HS, 8.0000 MHz
     SW:              mikroC PRO
*/
#define Digit1 PORTD.B0 //  DIGIT 1 FROM LEFT , THOUTHAND
#define Digit2 PORTD.B1 // DIGIT 2 FROM LEFT , HUNDRED
#define Digit3 PORTD.B2 // DIGIT 3 FROM LEFT , TENS
#define Digit4 PORTD.B3 // DIGIT 4 FROM LEFT ,  ONES

unsigned char Display (unsigned char digit)
  {
    unsigned char pattern;
    unsigned char  SEGMENT_MAP[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
    pattern =  SEGMENT_MAP[digit] ;  //The pattern to return
    return (pattern);
  }

void main() {
unsigned char DD1,DD2, DD3,DD4 ;

float result; //
unsigned int result1;
  ADCON1= 0;           //
  TRISA.B0=1; // AN0 INPUT
  TRISD = 0;            // Configure PORTD as outputs , COMMON CATHODES
  TRISB = 0;            // Configure PORTB as outputs ,7 SEGMENT DATA PORT

Digit1 = 0;            //Disable digit 1
Digit2 = 0;            //Disable digit 2
Digit3 = 0;            //Disable digit 3
Digit4 = 0;            //Disable digit 4


  while(1){
  result=ADC_Read(0);  // Read analog value from channel 0 ,0 to 1023 
  result = result * (5000.0/1023.0); // input analog voltage
  result = result /10.0 ; // input temp in C for LM35 0.0 to 150.0
   ///////////
 result = result *10.0 ; // float 0.0 to 1500.0
 result1=result; //integer 0 to 1500 to get fraction
 /////////////
       DD1 = result1 / 1000;       //Extract DD1 from result >>THOUTHAND(hundred)
       PORTB = Display(DD1);    //Display the DD1
       Digit1 = 1;             //Enable digit 1
       Delay_Ms(10);            //a short 10ms delay
       Digit1 = 0;             //Disable digit 1
 /////////
       DD2 = (result1/100) % 10;        // DD2 digit >>>HUNDRED (tens)
       PORTB = Display(DD2);    //Display the DD3
       Digit2 = 1;             //Enable digit 2
       Delay_Ms(10);            //a short 10ms delay
       Digit2 = 0;             //Disable digit 2
   ////////////
   DD3 = (result1/10) % 10;       //Extract DD3 from result >>TENS (ones)
       PORTB = Display(DD3);    //Display the DD3
       Digit3 = 1;             //Enable digit 3
       Delay_Ms(10);            //a short 10ms delay
       Digit3 = 0;             //Disable digit 3
   /////////
   DD4 = result1 % 10;       //Extract DD4 from result >>ONES(fraction)
       //PORTB = 0x39;    //Display C CHARACTER
   PORTB = Display(DD4);
       Digit4 = 1;             //Enable digit 4
       Delay_Ms(10);            //a short 10ms delay
       Digit4 = 0;             //Disable digit 4
    }
}


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


فكرة إنشاء ثرموستات باستخدام المقاومة السالبة NTC والمحول ADC ووحدة العرض LCD مع المترجم ميكرو سى
المقاومة السالبة المستخدم من النوع NTC / NTSA0WB203 وهذا النوع موجود فى برنامج ISIS .
هذه المقاومة لها معامل أو ثابت يسمى بيتا “ = 4050” ، ولها مقاومة قيمتها 20 كيلوأوم عند درجة حرارة 25 درجة مئوية .

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



يتم تشكيل مقسم جهد من مصدر جهد (بطارية ، على سبيل المثال ) والمقاومة السالبة NTC ومقاومة ثابتة R1 بقية 10 كيلوأوم ، وحساب درجة الحرارة من المعادلات التالية :



كود:
VT=VB * RT/R1+RT
VB*RT = VT*R1 + VT * RT 
VT*R1= RT(VB-VT)
RT = VT*R1/(VB-VT) = 10000VT/(5-VT)

البرنامج :

كود:
// LCD module connections
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connections
float tv,tr,temp,y;                 //Equation variables
   unsigned unsigned int value;
   int Tc ;
   char text [7] ;

void main() {

   lcd_init();
   Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);
  Lcd_Out(1,1,"ADC NTC TEMP." );
   while (1) {
      value = ADC_Read(0);

      tv = 5.0 * value / 1023.0;

      tr = tv * 10000.0 / (5.0 - tv);

      y = log(tr/20000.0);
       y = (1.0/298.15) + (y *(1.0/4050.0));

      temp=1.0/y;
      temp = temp -273.15;
	  Tc = temp ;
	  IntToStr(Tc , text);
	  Lcd_Out(2,1,text);
          Lcd_Chr_Cp(223);
	  Lcd_Chr_Cp('C');

   }
}


ayam
:: مهندس جيد ::
تاريخ التسجيل: Dec 2005
المشاركات: 287
نشاط [ ayam ]
قوة السمعة:
قديم 19-07-2017, 01:58 PM المشاركة 141   
افتراضي


ادعو المولى ان بجعله في ميزان حسناتك , من اروع ما قرأت من الشروحات


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 24-07-2017, 01:02 AM المشاركة 142   
افتراضي


فهم المقاطعات في الميكروكنترولر 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 .


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 24-07-2017, 01:05 AM المشاركة 143   
افتراضي


تدريب 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 ويلف مرة أخرى من الصفر ويستمر فى ذلك . فى أى وقت تقوم بالضغط على المفتاح الضاغط ، تحدث المقاطعة ، وسوف يستجيب المعالج إليها عن طريق تغيير حالة الليد الأصفر ، بعد ذلك سوف يستأنف مهمة العد .


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 24-07-2017, 01:10 AM المشاركة 144   
افتراضي


تدريب 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
    }
  }
}



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