البرنامج : يتناول البرنامج تهيئة السجلات ADCON0, ADCON1 . يستخدم الطرف RA0/AN0 كمدخل تناظرى. فى السجل ADCON0 يتم تحديد : CHS0=0 وCHS1=1 و CHS2=1 و CHS3=1أى يتم توصيل القناة AN0 داخليا . جعل الخانة VCFG=0 يؤدى إلى اختيار جهد المصدر +5V كجهد مرجع لموديول المحول A/D . مع ذلك فإن المترجم MikroC Pro for PIC يتضمن مكتبة تحتوى على الدالة المسماة ADC_Read() والتى (فى الوضع الافتراضى) تستخدم نبضات الساعة RC الداخلية لعمل التحويل ADC . التعليق على البرنامج : /*
Analog-to-digital converter
Oscillator @ 4MHz, MCLR Enabled, PWRT Enabled, WDT OFF
*/
1- التعريف بتوصيلات وحدة LCD مع الميكروكونترولر // LCD module connections
· 6 أطراف sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_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;
· 6 خانات تحكم sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_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
2- تعريف (إعلان) الرسائل : // Define Messages
· الرسالة الأولى على شكل مصفوفة " [] " حروف char" " باسم "message1" تنص على " ADC Value= " يليها الإعلان عن مؤشر "*" لمتغير من نوع الحروف "char" باسم temp" " وإعطاءة قيمة ابتدائية "0000" أى نص مكون من أربع أرقام (مصفوفة صف من أربع عناصر) قيمته الابتدائية هى أصفار . char message1[] = "ADC Value= ";
char *temp = "0000";
· تعريف (إعلان) عن متغير لحفظ نتيجة التحويل ADC unsigned int adc_Value;
3- بداية الدالة الرئيسية : · أولا أعدادات الميكروكونترولر : void main() {
# تهيئة الطرف RA0/AN0 كمدخل تناظرى وباقى الأطراف كمداخل / مخارج رقمية ADCON1 = 0b00001110 ; // RA0/AN0 is analog input
# تخصيص موديول المحول داخليا للقناة AN0 . ADCON0 = 0 ; // Analog channel select @ AN0
# تهيئة جميع أطراف المنفذ PORTB والمنفذ PORTA كمخارج فيما عدا طرف الدخل التناظرى AN0 TRISB = 0b00000000; // PORTB All Outputs
TRISA = 0b00000001; // PORTA All Outputs, Except RA0
· ثانيا إعدادات وحدة LCD : # التهيئة Lcd_Init(); // Initialize LCD
# مسح الشاشة Lcd_Cmd(_LCD_CLEAR); // CLEAR display
# منع ظهور المؤشر Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
· كتابة الرسالة الأولى(ثابتة) " " ADC Value= بدءا من الصف الأول والعامود الأول Lcd_Out(1,1,message1); // Write message1 in 1st row
· الدخول إلى حلقة do{….}while(1) الغير منتهية وتبدأ بتنفيذ: do {
# قراءة المدخل التناظرى من القناة AN0 بالدالة ADC_Read(0) ثم نسخ النتيجة للمتغير adc_value adc_value = ADC_Read(0);
# قسمة محتويات المتغير adc_value على 1000للحصول على عدد الآلاف الصحيحة وإضافة العدد 48 لتحويله إلى كود أسكى ونسخ النتيجة فى الخانة 0 (خانة الآلاف – العنصر الأول من المصفوفة ) للمتغير temp temp[0] = adc_value/1000 + 48; // Add 48 to get the ASCII character value
# الحصول على العدد الصحيح للمئات عن طريق : قسمة محتويات المتغير adc_value على 100 ثم إيجاد باقى قسمة النتيجة على 10 وفى النهاية يتم إضافة العدد 48 لتحويل النتيجة إلى كود أسكى ونسخ النتيجة فى الخانة 1 (خانة المئات- العنصر الثانى من المصفوفة) فى المتغير temp temp[1] = (adc_value/100)%10 + 48;
# كرر للحصول على العدد الصحيح للعشرات ونسخه فى الخانة 2 (العشرات) للمتغير temp temp[2] = (adc_value/10)%10 + 48;
# كرر للحصول على العدد الصحيح للآحاد ونسخه فى الخانة 3 (الآحاد) للمتغير temp temp[3] = adc_value%10 + 48;
# ثم كتابة (إرسال) محتويات المتغير temp كنص يبدأ من الصف الأول والعامود الحادى عشر حتى يتم كتابة بعد الرسالة الأولى الثابتة مباشرة . Lcd_Out(1,11,temp);
# التأخير 2 ثانية للسماح بمشاهدة وقراءة المعروض على الشاشة Delay_ms(2000);
# تكرار الخطوات السابقة لتحديث قيمة الدخل التناظرى ومن ثم المعروض على الشاشة . } while(1); }
كود HTML:
/* PIC16F877 Analog-to-digital converter Oscillator @ 4MHz, MCLR Enabled, PWRT Enabled, WDT OFF */ // LCD module connections sbit LCD_RS at RB0_bit; sbit LCD_EN at RB1_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 TRISB0_bit; sbit LCD_EN_Direction at TRISB1_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 // Define Messages char message1[] = "ADC Value= "; char *temp = "0000"; unsigned int adc_Value; void main() { ADCON0 = 0b00000000; // Analog channel select @ AN0 = DEFAULT ADCON1 = 0b00001110 ; // RA0/AN0 is analog input TRISB = 0b00000000; // PORTB All Outputs TRISA = 0b00000001; // PORTA All Outputs, Except RA0 Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // CLEAR display Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off Lcd_Out(1,1,message1); // Write message1 in 1st row do { adc_value = ADC_Read(0); temp[0] = adc_value/1000 + 48; // Add 48 to get the ASCII character value temp[1] = (adc_value/100)%10 + 48; temp[2] = (adc_value/10)%10 + 48; temp[3] = adc_value%10 + 48; Lcd_Out(1,11,temp); Delay_ms(2000); } while(1); }