2011年3月28日 星期一

DIY - PIC: PIC18F4550 A/D 程式 (四十六)

DIY - PIC PIC18F4550 A/D 程式 (四十六)

為了簡化A/D 程式,程式使用了頭文件 ()adc.h 包函 OpenADC (設定) ConvertADC (轉換) BusyADC (狀態) ReadADC (讀取) 等等,只需要呼叫以上的副程式。讀取數值後,將數值換算出真正的數值,數值資料輸出到 LCD 1602 作出顯示。數值資料包括A/D 轉換及計算出電壓數值,LED 閃動作為程式偵測作用。

PIC18F4550 ADC 流程圖

主程式:
void main(void)
{
    //                1234567890123456               
    char LCD_name[] ="BWS A/D AN0 v1  ";
    char LCD_name2[]="                ";
int i;
unsigned int timeout=0;
char data;


// Variables for ADC
    float adc0_volt;
    unsigned int adc0_dec;
    unsigned int adc0_volt1;
    unsigned int adc0_volt2;
    char Buf[17];

    //ADCON0 = 0x00;               // Disable the AD converter
    //ADCON1 = 0x0F;               // Set all ports to digital
    TRISA = 0b00000001;            // Setup RA0=Input RA1=Output
    TRISB = 0b00100000;            // Setup RB5=Input

    // Initialise LCD
     OpenXLCD(FOUR_BIT&LINES_5X7); // Init the LCD Display
    while(BusyXLCD());
    WriteCmdXLCD(BLINK_OFF & CURSOR_OFF ); 
    while(BusyXLCD());    
    stdout = _H_USER;             // Redirect I/O to LCD
    //Delay10KTCYx(24);           // 10,000x24x1/12us = 20ms
    LcdSetLine1();                // Put cursor on start of line 1
    putsXLCD(LCD_name);           // Display text

     OpenADC(ADC_FOSC_32 &        // A/D clock source set to 32Tosc
             ADC_RIGHT_JUST &     // ADRESH:ADRESL from roght
             ADC_20_TAD,          // A/D Acquisition time: 20TAD
             ADC_CH0 &            // Analog Channel0 AN0
             ADC_INT_OFF &        // ADC Interrupt off
             ADC_VREFPLUS_VDD &   // Vref+ = VDD
             ADC_VREFMINUS_VSS,   // Vref- = VSS
             0b1110               // ADCON0 = 7 = 00001110=AN0 Analog
             );
   
    while(1)
    {
           //key = PORTBbits.RB5;
        ConvertADC();            // Start an A/D Conversion
        while(BusyADC());        // Wait for Conversion Finished
        adc0_dec=ReadADC();      // Read A/D Result

        // Convert Floating Point to Decimal
        adc0_volt=0.00488758553*adc0_dec;
        adc0_volt1=(unsigned int)adc0_volt;
        adc0_volt2=(unsigned int)((adc0_volt-adc0_volt1)*10);

        sprintf(Buf,"D=%u V=%u.%uV        ",adc0_dec,adc0_volt1,adc0_volt2);
        LcdSetLine2();            // Put cursor on start of line 2
        putsXLCD(Buf);            // Display Content

        LATAbits.LATA1 = 1;       // RA0=1 LED=ON Scope=1
        Delay10KTCYx(240);        // 10,000 x 1 x (4 x 0.05us) = 2ms
                                  // Scope = 2ms
         
        LATAbits.LATA1 = 0;       // RA0=0 LED=OFF Scope=50ms
    } // End While
}

A/D 電路運作中
0×0.00488V = 0.0V
440×0.00488V = 2.1V
1020×0.00488V = 4.9V
610×0.00488V = 2.9V 與數字萬用錶 3.00V比較

沒有留言:

張貼留言