برمجة المقطعات لتوفير الطاقة

2013-08-19

السبات وبرمجة المقاطعات لتوفير الطاقة

ذكرنا في المقالة السابقة مثال جهاز تحكم عن بعد وذكرنا أنه لا ينبغي لك أن تظل تقيس هل ضغط المستخدم الزر 16 مليون مرة في الثانية لتستهلك البطارية. وعرضنا أول طريقة للحل وهي بالتحكم في تردد المتحكم الدقيق فننظر هل ضغط المستخدم الزر 500 مرة في الثانية مثلا.

في هذه المقالة سنشرح جانب آخر وطريقة أخرى يمكن إضافتها إلى الطريقة السابقة وهي اسبات المتحكم الدقيق (أي إدخاله في سبات)

الطريقة باختصار أننا سنطلب من المتحكم الدقيق أن يدخل في سبات لا يستهلك خلاله إلا مقدار هامشي جدا من الطاقة ويستيقظ عندما يستشعر تغير حالة الزر.

هناك عدة مستويات من توفير الطاقة تقدمها لنا معالجات AVR وهي من الأقل توفيرا إلى الأعلى توفيرا

  • SLEEP_MODE_IDLE
  • SLEEP_MODE_ADC
  • SLEEP_MODE_PWR_SAVE
  • SLEEP_MODE_STANDBY
  • SLEEP_MODE_PWR_DOWN

تختلف فيما بينها في الوحدات المطفئة لتوفير استهلاكها. عليك مراجعة ال datasheet لمعرفة التفاصيل مثلا طور stand by تحتاج مذبب خارجي. في مثالنا نحن نريد Pin Change ونلاحظ أنه مدعوم حتى في طور الإطفاء التام SLEEP_MODE_PWR_DOWN.

نحن نعلم أن المعالج بشكل عام ينفذ التعليمات بالتسلسل ما لم تكن تعليمة تفرع branch كان تقول إذا حصل كذا اذهب إلى العنوان كذا (أو الدالة كذا). تستطيع أن تتخيل أن المقاطعات Interrupts هي أحداث تستدعي تنفيذ عنوان ما (في لغة التجميع) أو دالة ما (في لغة سي) يعرف بمعالج المقاطعة interrupt handler أو Interrupt Service Routine ويشار لها اختصارا ISR

هناك عدة أنواع من المقاطعات منها الخارجية مثل تغير حالة أحد المداخل المخصصة لذلك (في حالة Atmega328 في Uno هي PIN2 و PIN3) وهي أنواع

  • عند أي تغيير بمعنى من الصفر إلى الواحد أو بالعكس
  • كلما أصبحت القيمة منخفضة (يظل يحدث بشكل متكرر)
  • عندما تنزل من واحد إلى صفر (الصفر الذي بعد الصفر لا يعد نزولا نزولا)
  • عندما تصعد من صفر إلى واحد

ومنها البرمجية أو الداخلية مثل انقلاب العداد (يصل لأعلى حد له مثل 255 فيقلب للصفر) أو وصوله للقيمة المطلوبة ومنها وصول بيانات بأحد طرق التواصل بين الدارات مثل I2C أو UART أو SPI أو الانتهاء من تحويل المدخلة التناظرية إلى رقمية ADC وغيرها

دالة معالجة المقاطعة يجب أن لا تعبث بمسجلات الحالة وغيرها حيث عليها أن تحفظها ثم تعمل ما شاءت ثم تسترجعها ثم تعود بالتعليمة RETI لكن إن استخدمت لغة سي فإنها ستتكفل بذلك.

إذا كنت تريد القيام بعمليات ذرية (أي لا تريد أي يحول بين أجزائها أي شيء) دون أن تحدث أي مقاطعة يمكنك تعطيل المقاطعة عبر عمل CLEAR لعلامة تفعيل المقاطعة بالتعليمة CLI ثم تقوم بما شئت ثم تفعلها من جديد بالتعليمة SEI

الدالة AttachInterrupt جعلت الأمر سهل جدا انظر هذا المثال الذي يسبت ويصحو عند يصحو خفض حالة PIN2 إلى الصفر بوصله بالأرضية GND وعندها يرمش حالة ضوء LED ثم يعود للسبات

#include <avr/interrupt.h> #include <avr/power.h> #include <avr/sleep.h> #include <avr/io.h> // void setup(void) { DDRD &= B00000011; // set Arduino pins 2 to 7 as inputs, leaves 0 & 1 (RX & TX) as is DDRB = B00000000; // set pins 8 to 13 as inputs PORTD |= B11111100; // enable pullups on pins 2 to 7 PORTB |= B11111111; // enable pullups on pins 8 to 13 pinMode(13,OUTPUT); // set pin 13 as an output so we can use LED to monitor digitalWrite(13,HIGH); // turn pin 13 LED on } // void loop(void) { // Stay awake for 1 second, then sleep. // LED turns off when sleeping, then back on upon wake. delay(1000); sleepNow(); } // void sleepNow(void) { // Set pin 2 as interrupt and attach handler: attachInterrupt(0, pinInterrupt, LOW); delay(100); // // Choose our preferred sleep mode: set_sleep_mode(SLEEP_MODE_IDLE); // // Set sleep enable (SE) bit: sleep_enable(); // // Put the device to sleep: digitalWrite(13,LOW); // turn LED off to indicate sleep sleep_mode(); // // Upon waking up, sketch continues from this point. sleep_disable(); digitalWrite(13,HIGH); // turn LED on to indicate awake } // void pinInterrupt(void) { detachInterrupt(0); }

في gcc-avr أقصد دون مكتبة أردوينو نستخدم الماكرو ISP متبوع باسم المقاطعة كما في المثال التالي من

http://www.scriptoriumdesigns.com/embedded/interrupt_examples.php

#define OUTPORT PORTC volatile u8 Int_flag = 0; ISR( INT0_vect ) { OUTPORT ^= 0x01; // toggle LED }

لعلك لاحظت استخدم المحددة volatile (والتي هي ضد register) وذلك يعني أنها في الذاكرة رام وليست المسجلات registers

وبما أن المقالة عن توفير الطاقة يجدر بنا أن نقول أن منظمات الفولتية و BOD تستهلك الطاقة لكن الأولى يمكننا أن نستغني عنها أما الثانية فلا ينصح بذلك.

جزء كبير من هذا المقال جاء من مثال جهاز تحكم في باب الكراج

2


Test User