2016-08-30 97 views
1

我跟着this Tutorial并更改了我的微控制器16f1827的代码。我也改变了代码的功能。如果ADC值超过最大值的一半,它应该打开LED。 ADC值,如果不到一半,则关闭LED。PIC 16f1827 ADC转换太慢XC8

// CONFIG 
#pragma config FOSC = HS  // Oscillator Selection bits (HS oscillator) 
#pragma config WDTE = OFF  // Watchdog Timer Enable bit (WDT disabled) 
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) 
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled) 
#pragma config LVP = OFF  // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming) 
#pragma config CPD = OFF  // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) 
#pragma config WRT = OFF  // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control) 
#pragma config CP = OFF  // Flash Program Memory Code Protection bit (Code protection off) 

#include <xc.h> 
#include <pic16f1827.h> 

#define _XTAL_FREQ 8000000 

void ADC_Init() 
{ 
    ADCON0 = 0x81;    //Turn ON ADC and Clock Selection 
    ADCON1 = 0x00;    //All pins as Analog Input and setting Reference Voltages 
} 

unsigned int ADC_Read(unsigned char channel) 
{ 
    if(channel > 7)    //Channel range is 0 ~ 7 
    return 0; 

    ADCON0 &= 0xC5;    //Clearing channel selection bits 
    ADCON0 |= channel<<3;  //Setting channel selection bits 
    __delay_ms(2);    //Acquisition time to charge hold capacitor 
    GO_nDONE = 1;    //Initializes A/D conversion 
    while(GO_nDONE);    //Waiting for conversion to complete 
    return ((ADRESH<<8)+ADRESL); //Return result 
} 

void main() 
{ 
    unsigned int a; 
    TRISA = 0xFF;     //Analog pins as Input 
    TRISB = 0x00;     //Port B as Output 
    //TRISC = 0x00;     //Port C as Output 
    ADC_Init();     //Initialize ADC 

    do 
    { 
    a = ADC_Read(0);   //Read Analog Channel 0 
    //PORTB = a;     //Write Lower bits to PORTB 
    //PORTC = a>>8;    //Write Higher 2 bits to PORTC 


if(a > 512){ 
PORTBbits.RB7 = 1; 
}else{ 
PORTBbits.RB7 = 0; 
} 


    __delay_ms(100);   //Delay 
    }while(1);     //Infinite Loop 
} 

该代码在XC8中编译时没有错误。问题是PIC检测到ADC变化太慢。如果我拿到输入引脚并将其连接到正参考值,它会以延迟2秒的方式打开LED。将ADC输入更改为0v时发生同样的情况。所有更改都检测得非常慢。 ADC为什么如此慢地工作?

+0

你可以发布'__delay_ms()'的内容吗?这可能是额外时间的来源。你的晶体实际上是8MHz?您需要设置哪些寄存器才能正确配置时钟? – rjp

+0

这是我在我的MPLAB X项目中的完整代码。我没有一个晶振,我只是使用裸IC。 –

+0

我会参考提供'__delay_ms()'的库的文档,并确保它不是在编译时没有正确设置的配置。你试图在循环的迭代之间延迟100毫秒,但你看到的是~2秒,所以'__delay_ms()'函数在确定要循环多少个循环迭代和多快微正在执行它们。 – rjp

回答

1

您链接的教程使用带有8MHz晶体振荡器的PIC16F877A,而您似乎试图使用带有内部振荡器而不是外部振荡器的PIC16F1827。如你所做的那样仅仅改变PIC头文件是不够的。您还必须设置所需的振荡器模式,并注意两部分之间不同的其他配置选项。我不确定,但我认为16F1827的默认内部振荡器频率为1MHz,而不是8MHz。这可能会解释您遇到的问题。

顺便说一句:不要试图欺骗你的代码。确保你正确地配置你的微控制器,否则它们会迟早地将你烧伤。