# PIC18F4520 ADC Conversion in MC18

I have a dilemma.

I need to read ADC values from PIC18F4520. My configuration, and code, is as follows:

#define OSC INTIO67

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;

while (1) {
}
}


The issue is this:

1. When I run it in MPLAB v8.x, my reading is slightly off, and terminates my debugging.
2. 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).

-
Just to clarify: are you debugging a real device or are you simulating it? Are you including the right header for the device (no includes shown in your code)? –  PetPaulsen May 4 '12 at 9:24
I'm debuggging a real device. I've only set WDT to OFF and LVP to OFF. My includes are 18f4520.h, as well as adc.h. –  Buhake Sindi May 4 '12 at 10:58

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:

• In your code you are never starting the ADC conversion by calling ConvertADC.
• You are configurating port a as output by setting TRISA = 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.

-
Thanks, so how do I set the clock signal of ADC to Fosc (in this case, 32Mhz)? Also, I do have ConvertADC(), it was a typo. Sorry. –  Buhake Sindi May 4 '12 at 10:53
Again: you have to verify that the aquisiton time ($T_{AD}$) is met. On page 359 you will see the minimum $T_{AD}$ is 0.7us. So for a higher oscillator frequency you have to select a bigger divisor. Table 19-1 will give you an overview. I would recommend you to read the datasheet, at least section 19, ADC. –  PetPaulsen May 4 '12 at 11:24