在PIC 12F675中不能进行模拟读取

在PIC 12F675中不能进行模拟读取,c,microcontroller,pic,C,Microcontroller,Pic,在我的代码中,我想读取电池的电压,如果电压大于3V,则会关闭LED。但即使电压为5v,LED也会一直亮起。当我在不同的GPIO中添加更多LED并将其关闭0/1时,GPIO2会关闭。我正在使用PIC12F675。 AN1是我的模拟读卡器引脚,即GPIO1。 GPI02是我的LED输出引脚 // CONFIG #pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on

在我的代码中,我想读取电池的电压,如果电压大于3V,则会关闭LED。但即使电压为5v,LED也会一直亮起。当我在不同的GPIO中添加更多LED并将其关闭0/1时,GPIO2会关闭。我正在使用PIC12F675。
AN1是我的模拟读卡器引脚,即GPIO1。
GPI02是我的LED输出引脚

// 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/                      
        }
    }
}
//配置
#pragma config FOSC=INTRCIO//振荡器选择位(INTOSC振荡器:GP4/OSC2/CLKOUT引脚上的I/O功能,GP5/OSC1/CLKIN上的I/O功能)
#pragma config WDTE=OFF//看门狗定时器启用位(WDT禁用)
#pragma config PWRTE=OFF//通电定时器启用位(PWRT禁用)
#pragma config MCLRE=ON//MCLR
#pragma config BOREN=OFF//Brown out检测启用位(BOD禁用)
#pragma config CP=OFF//代码保护位(程序内存代码保护被禁用)
#pragma config CPD=OFF//数据代码保护位(禁用数据内存代码保护)
//#pragma config语句应位于项目文件includes之前。
//使用项目枚举而不是#定义用于打开和关闭。
#包括
#定义频率为4000000//4MHZ的晶体
真空总管(真空){
无符号整数adcVal;
双电压;
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;//通道2
ADCON0bits.CHS0=1;
ADCON0bits.CHS1=0;//AN1
ADCON0bits.ADON=1;//打开它
ADCON0bits.GO=1;
ADCON0bits.ADFM=1;
而(1){
__延期付款(5);
ADCON0bits.ADON=1;
GO_n done=1;
while(GO\u nDONE);//等待ADC完成
adcVal=((无符号整数)ADRESH=3.0){
GPIObits.GP2=0;//LED熄灭
}否则{
GPIObits.GP2=1;//发光二极管亮起/
}
}
}

您的计算
adcVal/1023
是一个整数计算,对于
adcVal
的范围为0…1023,始终为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/                      
        }
    }
}
//配置
#pragma config FOSC=INTRCIO//振荡器选择位(INTOSC振荡器:GP4/OSC2/CLKOUT引脚上的I/O功能,GP5/OSC1/CLKIN上的I/O功能)
#pragma config WDTE=OFF//看门狗定时器启用位(WDT禁用)
#pragma config PWRTE=OFF//通电定时器启用位(PWRT禁用)
#pragma config MCLRE=ON//MCLR
#pragma config BOREN=OFF//Brown out检测启用位(BOD禁用)
#pragma config CP=OFF//代码保护位(程序内存代码保护被禁用)
#pragma config CPD=OFF//数据代码保护位(禁用数据内存代码保护)
//#pragma config语句应位于项目文件includes之前。
//使用项目枚举而不是#定义用于打开和关闭。
#包括
#定义频率为4000000//4MHZ的晶体
真空总管(真空){
无符号整数adcVal;
双电压;
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;//通道2
ADCON0bits.CHS0=1;
ADCON0bits.CHS1=0;//AN1
ADCON0bits.ADON=1;//打开它
ADCON0bits.GO=1;
ADCON0bits.ADFM=1;
而(1){
__延期付款(5);
ADCON0bits.ADON=1;
GO_n done=1;
while(GO\u nDONE);//等待ADC完成
adcVal=((无符号整数)ADRESH=614){//3.0V的值
GPIObits.GP2=0;//LED熄灭
}否则{
GPIObits.GP2=1;//发光二极管亮起/
}
}
}

adcVal/1023始终为0!!!!这是一个整数计算。您应该完全避免浮点运算,并将结果与整数值进行比较……或者,如果您想要更可读的数字(精度更低),请使用adcVal,乘以50,然后除以1024(1024更快!)。精度更低,但如果(adcVal*50/1024>=30).它解决了模拟读取问题。但当我为led打开/关闭另一个GPIO时,为什么所有led都处于低模式。
如果(adcVal>=614){//3.0V GPIObits的值。GP2=0;//led关闭GPIObits.GP4=0;}其他{GPIObits.GP2=1;///GPIObits.GP4=1;}
GP4的TRIS状态寄存器是否正确?可能是过电流问题?这完全是另一回事,可能适合另一个问题。