I'm using a PIC18F4480 and attempting to setup one ADC channel for now, AN0.
my input circuit consists of a pot voltage divider into a voltage follower opamp as a buffer. The buffer should take care of any input impedance issues, right? i have a multimeter on the input pin and can see my voltage vary nicely from 0-5Vish.
I'm writing in C and and using this config:
Code:
int getADC (unsigned int channel){
int adcResult = 0;
OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_12_TAD, ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, ADC_16ANA);
msDelay(10);
ConvertADC(); // Start conversion
while( BusyADC() ); // Wait for conversion to complete
adcResult = ReadADC(); // Get value
CloseADC();
msDelay(10);
return adcResult;
}
When i run the program and call this function continuously from a while(1) loop in main i basicaly get either '1023' or '0023'. i sometimes see other number flicker on the LCD but those are it 99.9% of the time.
Does this give you guys any sort of clue as to whats wrong? Could it be a twos compliments number flopping pos/neg around zero? it behaves as if my input is binary.. about halfway around the pot it flips to the other value.
Is there any harm is setting all channels to analog in the ADCconfig? I've tried just one (AN0) and also all of them w/ no change in results.
As you can see i'm using a TAD of 12 and an freq of OSC/32 .. i'm running at 20MHz and this is the recommended freq. I'm a bit unclear on figuring TAD.
there is a bug in the C18 ADC libraries. using the Watch function i verified the reference registers werent being set right so i hardcoded ADCON1 adn voila!
int getADC (unsigned int channel){
int adcResult = 0;
msDelay(10);
//OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_12_TAD, ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, ADC_16ANA);
ADCON1=0b00001011;
if(channel==1){
ADCON0=0b00000000; // ANA0
}else if(channel==2){
ADCON0=0b00000100; // ANA1
}else if(channel==3){
ADCON0=0b00001000; // ANA2
}else if(channel==4){
ADCON0=0b00001100; // ANA3
}
msDelay(1);
ADCON2=0b10101010;
ADCON0bits.ADON = 1; // Enable the A/D
msDelay(1);
ConvertADC(); // Start conversion
while( BusyADC() ); // Wait for conversion to complete
adcResult = ReadADC(); // Get value
CloseADC();
return adcResult;
}
its supposed to be 'super relaxed'. if that first msDelay is less than 10ms i get some cross talk between channels. I have a variable input on AN0 and AN1-3 grounded. w/ the msDelay(10) there i get my variable result on 1 and 1 or 2 (very close to zero) on the rest. good.
the problem is now that everything works fine from digital values 100-1023. however instead of dropping to 99 below 100 it goes to 990 and continues to drop to 020.. it gets offset a place. any ideas there? hrmm
well i made it work w/ a bunch of conditional LCD writes based on the integer's length. works like a champ i must say, but i'm afraid i'm not being effecient enough for uC use.. still seems to run very fast though *shrug*
talking to myself like this is like therapy i guess its working