Не могу взять Аналоговое чтение в ПИК 12F675 - PullRequest
1 голос
/ 25 марта 2019

В моем коде я хочу прочитать напряжение от батареи, и если напряжение больше 3 В, то оно выключено светодиодами. Но светодиод всегда включен, даже когда напряжение составляет 5 В, и когда я добавляю больше светодиодов в другой GPIO и поворачиваю их 0/1, тогда GPIO2 выключается. Я использую PIC12F675.
AN1 - это мой аналоговый контакт считывателя GPIO1.
GPI02 - это мой светодиодный выходной вывод.

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON     // MCLR
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

#define _XTAL_FREQ 4000000  // 4MHZ crystal

void main(void) {
    unsigned int adcVal;
    double voltage;
    int i=0;
    TRISIObits.TRISIO1 = 1;
    TRISIObits.TRISIO2 = 0;
    TRISIObits.TRISIO3 = 0;

    ANSELbits.ADCS0 = 1;
    ANSELbits.ADCS1 = 0;
    ANSELbits.ADCS2 = 1; //FOSC/16
    ANSELbits.ANS1 = 1; //channel 2
    ADCON0bits.CHS0 = 1;
    ADCON0bits.CHS1 = 0; //AN1
    ADCON0bits.ADON = 1; //Turn it on
    ADCON0bits.GO = 1;
    ADCON0bits.ADFM = 1;
    while (1) {
        __delay_us(5);
        ADCON0bits.ADON = 1;
        GO_nDONE = 1;
        while (GO_nDONE); //Wait for ADC to complete
        adcVal = (((unsigned int) ADRESH << 8) + ADRESL);
        ADCON0bits.ADON = 0;
        voltage = ((double) (adcVal / 1023)*5.0);

        if (voltage >= 3.0) {
            GPIObits.GP2 = 0; //LED off      

        } else {
            GPIObits.GP2 = 1; // LED On/                      
        }
    }
}

1 Ответ

1 голос
/ 25 марта 2019

Ваше вычисление adcVal/1023 является целочисленным вычислением и для диапазона 0 ... 1023 для adcVal всегда 0 (или 1 для 1023).

Лучше всего вообще избегать вычисления с плавающей запятой:

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON     // MCLR
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

#define _XTAL_FREQ 4000000  // 4MHZ crystal

void main(void) {
    unsigned int adcVal;
    double voltage;
    int i=0;
    TRISIObits.TRISIO1 = 1;
    TRISIObits.TRISIO2 = 0;
    TRISIObits.TRISIO3 = 0;

    ANSELbits.ADCS0 = 1;
    ANSELbits.ADCS1 = 0;
    ANSELbits.ADCS2 = 1; //FOSC/16
    ANSELbits.ANS1 = 1; //channel 2
    ADCON0bits.CHS0 = 1;
    ADCON0bits.CHS1 = 0; //AN1
    ADCON0bits.ADON = 1; //Turn it on
    ADCON0bits.GO = 1;
    ADCON0bits.ADFM = 1;
    while (1) {
        __delay_us(5);
        ADCON0bits.ADON = 1;
        GO_nDONE = 1;
        while (GO_nDONE); //Wait for ADC to complete
        adcVal = (((unsigned int) ADRESH << 8) + ADRESL);
        ADCON0bits.ADON = 0;

        if (adcVal  >= 614) {            //value for 3.0V
            GPIObits.GP2 = 0; //LED off      

        } else {
            GPIObits.GP2 = 1; // LED On/                      
        }
    }
}
...