البرنامج : يوفر المترجم MikroC Pro for PIC بمكتبة بأربعة دوال لروتينات للتحكم فى PWM باستخدام الموديول CCP . هذه الروتينات هى : PWM1_Init(const long frequency) و PWM1_Set_Duty(unsigned short duty_ratio) و PWM1_Start(void) و PWM_Stop(void) البرنامج يعطى عشر مستويات مختلفة للتحكم فى شدة إضاءة الليد بتغيير دورة الخدمة من 0 إلى 250 بخطوة 25 فى كل مستوى . يتم تغيير دورة الخدمة عن طريق الضغط على المفاتيح الضاغطة UP , DOWN . التعليق على البرنامج: 1- مقدمة (رأس) البرنامج . /*
Pulse Width Modulation
Description: CCP module generating a PWM signal
MCU: PIC16F628A
Oscillator: XT, 4.0 MHz, MCLR Enabled
*/
2- تعريف الخانات بأسماء تعبر عن وظيفتها ومتعرف عليها . sbit UP at RB0_bit;
sbit DOWN at RB1_bit;
3- الإعلان عن المتغيرات unsigned short new_DC, current_DC;
4- إنشاء دالة تأخير لتلاشى تأثير حدوث إرتدادات فى المفاتيح . void debounce(){
Delay_ms(300);
}
5- بداية الدالة الرئيسية وفيها : void main() {
أ- إعدادات أطراف الميكروكونترولر : · فصل المقارنات للسماح باستخدام جميع الأطراف كمداخل / مخارج رقمية . CMCON = 0x07; // Disable comparators
· تصفير سجل المنفذ PORTB كحالة ابتدائية . PORTB = 0x00;
· أعداد أطراف المنفذ PORTB بحيث يكون RB0, RB1 كمداخل للمفاتيح و RB3 كمخرج PWM TRISB = 0b00000011; // RB0, RB1 input, RB3 (PWM1) output
ب- إعدادات نظام PWM · تردد الشكل الموجى فى الخرج 5KHz .
PWM1_Init(5000); // PWM module initialization (5KHz)
· تصفير متغير القيمة الجديدة للتيار المستمر DC والقيمة الحالية للتيار المستمر . new_DC = 0; // Initial value of variable Duty Cycle
current_DC = 0;
· بدء نظام PWM بقيمة "صفر" تيار مستمر PWM1_Start(); // Start PWM1 module with Zero DC
· ضبط دورة الخدمة لنظام PWM بالقيمة الموجودة فى متغير "القيمة الحالية" وهى فى البداية تكون بصفر . PWM1_Set_Duty(current_DC);
ت- الدخول إلى حلقة غير منتهية do{…..}while(1) حيث يتم تنفيذ : do {
· التحقق من أن مفتاح التزايد UP قد عكس وضعه أى تم الضغط عليه if (!UP){ // If the button connected to RB0 is pressed
· عندئذ يتم استدعاء دالة التأخير لتلاشى تأثير الارتدادات فى المفتاح debounce();
· التحقق من أن القيمة الجديدة لم ولن تتعدى أقصى قيمة وهى 250 . if (new_DC < 250) // Don't go above 250
· فإن كان كذلك يتم تزايد سجل القيمة الجديدة بمقدارخطوة أى بمقدار 25 ونسخ القيمة الجديدة مرة أخرى إلى سجل القيمة الجديدة . new_DC = new_DC + 25 ; // increment Duty Cycle by 25
}
· التحقق من أن مفتاح التزايد UP قد عكس وضعه أى تم الضغط عليه .
if (!DOWN) { // If the button connected to RB1 is pressed
· عندئذ يتم استدعاء دالة التأخير لتلاشى تأثير الارتدادات فى المفتاح debounce();
· التحقق من أن القيمة الجديدة لم ولن تصل لأدنى قيمة وهى الصفر . if (new_DC !=0) // Don't go below 0
· فإن كان كذلك يتم تناقص سجل القيمة الجديدة بمقدارخطوة أى بمقدار 25 ونسخ القيمة الجديدة مرة أخرى إلى سجل القيمة الجديدة .
new_DC= new_DC - 25 ; // Decrement Duty Cycle by 25
}
· التحقق من أن القيمة الجديدة لا تساوى القيمة الحالية if (current_DC != new_DC) {
· عندئذ يتم نسخ (مساواة) القيمة الجديدة إلى القيمة الحالية current_DC = new_DC ;
· ثم إعادة ضبط دورة الخدمة لنظام PWM بالقيمة الجديدة PWM1_Set_Duty(current_DC); // Change the current DC to new value
}
· وتكرار العملية بصفة مستمرة } while(1);
· نهاية الدالة الرئيسية . } // END main()
النتائج :