I have programmed the 10 bit internal ADC in PIC18F458 and displaying ADC output through UART. I have connected a 10 K pot to the ADC input RA0 and varying it to seeing the corresponding ADC output. Since, its a 10 bit ADC configured with +Vref = +Vdd = 5V and -Vref = Vss = Gnd, I presumed that for 0 Kohms, the ADC output should be 0 and for 10 K ohms, it should be 1023, however I have been getting some weird ADC output values when simulated in Proteus, and I am not sure on how to validate if its the right output or not. I have attached the images of the proteus simulations, data table and the code. And another thing is that, If I am using an unsigned int data type (ADC_data) to displaying the ADC outputs, then how come I am still getting negative values too?, provided +Vref = 5V and -Vref = Gnd = 0V. Can someone please explain this?
#define _XTAL_FREQ 20000000
#include<P18F458.h>
#include"UART.h"
#pragma config OSC=HS
#pragma config OSCS=OFF
#pragma config PWRT=OFF
#pragma config BOR=OFF
#pragma config WDT=OFF
#pragma config STVR=ON
#pragma config LVP=OFF
#pragma config CP0=OFF
#pragma config CP1=OFF
#pragma config CP2=OFF
#pragma config CP3=OFF
#pragma config CPB=OFF
#pragma config CPD=OFF
#pragma config WRT0=OFF
#pragma config WRT1=OFF
#pragma config WRT2=OFF
#pragma config WRT3=OFF
#pragma config WRTC=OFF
#pragma config WRTB=OFF
#pragma config WRTD=OFF
#pragma config EBTR0=OFF
#pragma config EBTR1=OFF
#pragma config EBTR2=OFF
#pragma config EBTR3=OFF
#pragma config EBTRB=OFF
#pragma config DEBUG=OFF
unsigned int ADC_data = 0;
void ADC_Init()
{
ADCON0bits.ADON = 1;
ADCON1bits.PCFG3 = 1;
ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG0 = 0;
ADCON1bits.ADFM = 0;
ADCON0bits.CHS0 = 0;
ADCON0bits.CHS1 = 0;
ADCON0bits.CHS2 = 0;
ADCON1bits.ADCS2 = 0;
ADCON0bits.ADCS1 = 1;
ADCON0bits.ADCS0 = 0;
}
void ADC_Convert()
{
ADCON0bits.GO_DONE = 1;
while(ADCON0bits.GO_DONE == 1);
ADC_data = (((unsigned int)ADRESH)<<8)|(ADRESL);
}
void main (void)
{
TRISAbits.TRISA0 = 1;
UARTInit();
ADC_Init();
while(1)
{
__delay_us(20);
ADC_Convert();
UARTNextLine("ADC Output is ");
UARTWriteInt(ADC_data,255);
}
}
Additional information :
Fosc = 20 MHz Tosc = 1/20MHz = 0.05us 32Tosc = 0.05us * 32 = 1.6us 11Tad = 11 * 1.6us = 17.6us
Note that , In the code I have given a delay of 20us before the A/D conversion starts and not 17.6us.
I am not sure if the ADC outputs what I have got is right or If there is some bug in the code that's generating inaccurate values. Any comments, suggestions and advice's on how to verify if my adc is working correctly would be helpful for me to continue and understand.
Thanking you all in advance ~VD