لنتعلم برمجة الأنظمة المدمجة

Embedded Systems Programming Bootcamp

كورس تعليمي يهدف الى اكسابك المعرفة اللازمة والمهارات التقنية المتعلقة ببرمجة وتطوير الأنظمة المدمجة وفهم خصائصها ومكوناتها

الصفحة الرئيسية
قائمة الدروس
خدمة RSS

للتواصل

7. برنامج لوميض الإضاءة الملونة RGB LED Blinking

2017-11-06






هذا درس تطبيقي مختصر عبارة عن شرح للبرنامج الذي قمنا بتجربته في الدرس الثالث وكتابة وفهم أول برنامج لنا على المتحكم دون إستخدام أي مكتبات برمجية مساعدة. ولتوضيح بعض النقاط فإنه بالإمكان تحميل دليل المستخدم User’s Guide للبورد من الرابط التالي:

http://www.ti.com/lit/ug/spmu296/spmu296.pdf

حيث نجد في (ص 7) الرسم التخطيطي block diagram للبورد والتي توضح لنا بأن الإضاءة الملونة RGB LED متصلة بمنافذ القراءة والكتابة GPIO Ports:

Tiva C LaunchPad Block Diagram
Tiva C LaunchPad Block Diagram

وفي (ص 20) من نفس المستند نجد مخطط البورد schematics والتي تبين لنا الأطراف التي تتصل بها الإضاءة الملونة:

حيث نجد أن:

نلاحظ أن إضاءة الـ RGB LED متصلة بالمنفذ F، ولذلك فإن جميع السجلات التي سنتعامل معها ستكون خاصة بهذا المنفذ.

تفعيل وميض الإضاءة الملون

للقيام بذلك، فإنه يتوجب علينا تتبع الخطوات التالية:

1. تفعيل المنفذ

يجب علينا أولاً تفعيل الساعة قبل أي شيء، وإلا فلن يعمل المنفذ. ومما سبق، يتضح لنا أن المنفذ الذي نريد تفعيله هو Port F، وبالعودة الى دليل البيانات datasheet (ص 340) والذي يشرح فيه السجل RCGCGPIO المسؤول عن تفعيل الساعة للمنفذ، نجد أنه لتفعيل Port F فإنه يتوجب علينا كتابة 1 الى البت الخامس bit 5 (علماً بأن العد يبدأ من 0). والتعديل عليها يكون إما بإسناد قيمة مباشره للسجل كما يلي:

SYSCTL_RCGCGPIO_R = 0x20; // 0010 0000

والأفضل من ذلك إستخدام إسلوب الـ bit shifting حيث أنها توضح أننا نريد تفعيل البت الخامس bit 5:

SYSCTL_RCGCGPIO_R = (1U << 5); // 0010 0000 

بعد تفعيل الساعة نحتاج الى الإنتظار قليلاً قبل بدء التعامل مع المنفذ ويمكن القيام بذلك بجلب القيمة الجديدة المكتوبة الى سجل المؤقت حيث أنه سيعطينا الوقت الكافي للتأكد من أنه قد تم فعلاً تفعيل المنفذ:

volatile unsigned long delay;
delay = SYSCTL_RCGCGPIO_R; 

2. تحديد إتجاه الأطراف

نريد في هذا البرنامج تفعيل الإضاءة الموجوده على المنفذ F في الأطراف 1 و 2 و 3 وجعلها output. ولذلك نقوم بكتابة 1 في البت المقابلة لكل طرف كما يلي:

GPIO_PORTF_DIR_R = 0xE; // 1110 -> PF0=0, PF1=1, PF2=1, PF3=1

ولأننا نسعى لأن يكون الكود الذي نقوم بكتابته واضحاً ولا يحتاج الى شرح self explanatory، فإنه بالإمكان وضع ماكرو لكل لون في الإضاءة مسنود اليها رقم البت المقابل للطرف الذي تتصل به بالمنفذ، ثم القيام بعملية إضافة البتات bits معاً عن طريق الـ bit shifting وإسناد النتيجة الى السجل كما يلي:

#define LED_RED    (1U<<1)		
#define LED_BLUE   (1U<<2)		
#define LED_GREEN  (1U<<3)		

GPIO_PORTF_DIR_R  = (LED_RED | LED_BLUE | LED_GREEN); // 1110

3. تفعيل الخصائص الرقمية للأطراف

مثل ما سبق، فنحن مهتمين فقط في الأطراف 1 و 2 و 3 في المنفذ F. ولتفعيلها نقوم بكتابة 1 في البت المقابل لكل طرف كما يلي:

GPIO_PORTF_DEN_R = 0xE; // 1110 -> PF0=0, PF1=1, PF2=1, PF3=1

أو من الممكن أن نقول:

GPIO_PORTF_DEN_R = (LED_RED | LED_BLUE | LED_GREEN); // 1110

3. الكتابة الى السجل

الإضاءة الحمراء متصلة بـ PF1. ولتشغيلها وإطفاء باقي الإضاءات

GPIO_PORTF_DATA_R = LED_RED; // 0010

وسننتظر بعد ذلك قليلاً بإستدعاء الدالة delay التي قمنا بكتابتها.

الإضاءة الزرقاء متصلة بـ PF2. ولتشغيلها وإطفاء باقي الإضاءات:

GPIO_PORTF_DATA_R = LED_BLUE; // 0100

نعود بعد ذلك للإنتظار قليلاً ثم نقوم بتشغيل الإضاءة الخضراء المتصلة بـ PF3. ولتشغيلها وإطفاء باقي الإضاءات:

GPIO_PORTF_DATA_R = LED_GREEN; // 1000

ثم ننتظر مرة أخرى ونقوم بتكرار عملية الوميض الى ما لا نهاية.

البرنامج

قم بإنشاء مشروع جديد كما فعلنا في الدرس الثالث وأضف الكود التالي ومن ثم قم بتجربته على البورد:

#define SYSCTL_RCGCGPIO_R   (*((volatile unsigned long *)0x400FE608))
#define GPIO_PORTF_DIR_R    (*((volatile unsigned long *)0x40025400))
#define GPIO_PORTF_DEN_R    (*((volatile unsigned long *)0x4002551C))
#define GPIO_PORTF_DATA_R   (*((volatile unsigned long *)0x400253FC))

#define LED_RED    (1U<<1)		
#define LED_BLUE   (1U<<2)		
#define LED_GREEN  (1U<<3)		

void delay ( ) {
  for (int i=0; i<5000000; i++);
}

int main ( ) {
  SYSCTL_RCGCGPIO_R = (1U << 5); // 0010 0000
  GPIO_PORTF_DIR_R  = (LED_RED | LED_BLUE | LED_GREEN); // 1110;
  GPIO_PORTF_DEN_R  = (LED_RED | LED_BLUE | LED_GREEN); // 1110; 

  while (1) {
    GPIO_PORTF_DATA_R = LED_RED;   
    delay();
    GPIO_PORTF_DATA_R = LED_BLUE;  
    delay();
    GPIO_PORTF_DATA_R = LED_GREEN; 
    delay();
  }	
}

ملاحظة: هذه المقالة تحت التحديث المستمر،، وملاحظاتكم وإقتراحاتكم ستساعد بإذن الله في إخراجها بالصورة التي كتبت من أجلها وهي تمهيد الطريق أمامكم لتعلم برمجة الأنظمة المدمجة