I have a dilemma.
I need to read ADC values from PIC18F4520. My configuration, and code, is as follows:
#define OSC INTIO67
int adc_result = 0;
void main(void)
{
OSSCON = 0x70; //Set it as 8Mhz.
OSCTUNEbits.PLLEN = 1; //Enable PLL 4x multiplier, thus we have 32 Mhz internal clock.
//Set PORTA direction ports as input
TRISA = 0xFF;
OpenADC( ADC_FOSC_32 &
ADC_RIGHT_JUST &
ADC_4_TAD,
ADC_CH0 &
ADC_REF_VDD_VSS &
ADC_INT_OFF, ADC_5ANA);
while (1) {
SetChanADC(ADC_CH0);
ConvertADC();
while (BusyADC());
adc_result = ReadADC();
}
CloseADC();
}
The issue is this:
- When I run it in MPLAB v8.x, my reading is slightly off, and terminates my debugging.
- I can't debug the PIC again since I get errors like "Cannot enter debug mode."
How do I fix those issues? Also, is my ADC configuration correct (seeing that ADC requires a clock to do ADC conversion) with my internal clock? Is this correct to set the clock signal to 32 MHz.
I am programming using PicKit2 (with the black button).
Best Answer
You are not setting the clock signal of the ADC to 32MHz. The parameter
ADC_FOSC_32
divides the clock by 32 (see page 225 of the datasheet). This ensures, together with the aquisition time select bits (ADC_4_TAD
in your case), the minimum (/maximum) A/D aquisiton time (see page 359). When you hurt these requirements you will not get valid/accurate results.With the equations given on page 228 you can do the math and verify, that the requirements are met.
Some other points:
ConvertADC
.a
as output by settingTRISA = 0x0;
but you want it to be configured as input (as your comment is saying).TRISA = 0xFF;
would configure all pins on port a as input.To expand a bit on the aquisiton time (\$T_{AD}\$): This time is needed for the internal circuitry to probably charge. When this time is too short, you will get no/bad results.
For 32Mhz (without divisor) \$T_{AD}\$ would be 31ns. That is too fast. At least 0.7us are required for the ADC to work probably. So you select a proper divisor to get \$T_{AD}\$ above 0.7us. A divisor of 32 will do it here, \$T_{AD} = 1\$us > 0.7us.