I'm trying to read an analog input on a PIC18F65J11, and I'm having trouble. I don't think the pin is set up correctly because I'm getting a 0 for the value I read in, and the input is measured to be about 1V (but can get up to 3V). I want to use Here is my code:

#include "p18f65j11.h"

/**CONFIGURATION **************************************************/
/* Device Configuration */
#pragma config XINST = OFF  // Turn off extended CPU instructions
#pragma config FOSC = HSPLL // HS oscillator will PLL that multiplies oscillator frequency by 4 (system clock is running at 16 MHz)
#pragma config FOSC2 = ON   // System clock selected by FOSC1:FOSC0 (used #config to set FOSC to HSPLL)
#pragma config DEBUG = ON   // Background debugger enabled; RB6 and RB7 are dedicated to In-Circuit Debug.
#pragma config WDTEN = OFF  // Disable watchdog timer.
#pragma config WDTPS = 8    // Watchdog timer poscaler select bits is 1:8 (not important b/c watchdog timer disabled).
#pragma config STVREN = OFF // Reset on stack overflow/underflow disabled.
#pragma config CP0 = OFF    // Program memory is not code-protected
#pragma config IESO = ON   // Oscillator Switchover mode disabled.
#pragma config FCMEN = OFF  // Fail-Safe Clock Monitor disabled.
#pragma config CCP2MX = DEFAULT // ECCP2/P2A multiplexed with RC1 instead of RE7 pin (doesn't matter b/c not using ECCP, which is pwm output)

int myVoltage;

void main(void)
{
myVoltage = 0;

// Configure clock registers (FOSC is set to HSPLL)
OSCCONbits.SCS1 = 0;    // SCS1:SCS0 = 00 means use primary
OSCCONbits.SCS0 = 0;    // clock source (CPU divider output) if FOSC2 is on (FOSC2 is indeed on from the #pragma config above)
OSCCONbits.IRCF2 = 1;   // IRCF2:IRCF0 = 110 means the internal oscillator is set to 4 MHz
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;
OSCCONbits.IDLEN = 0;   // on SLEEP instruction, device enters sleep mode instead of idle mode
OSCTUNEbits.PLLEN = 1;  // enable PLL (4x multiplier), so system clock is 4 * 4 MHz = 16 MHz
// Basically, I've just set it to use primary oscillator, told it the oscillator is
// 4 MHz, and told it to enable PLL so that my system clock is 16 MHz.

// Initialize Port A
TRISA &= 0;             // set Port A as outputs
LATA &= 0;              // all pins outputting 0
TRISAbits.RA0 = 1;      // set pin AN0 as input to read voltage

while(1) {
Delay10TCYx( 5 );
ConvertADC();               // initiate conversion of sensor1 @ AN0
while(BusyADC());           // waiting to complete conversion
printf("%i volts \n\r", myVoltage);
}
}


What am I doing wrong or missing? I suspect it's the OpenADC() part that may be wrong. I've got it using Fosc/8, result in least significant bits, 12 Tad, channel 0 (AN0 pin), interrupt off, VDD as the highest limit, and 0 so that all analog pins are analog.

-
All ADCs need a reference voltage. I'm not familiar with this hardware so I'm not sure if the reference voltage is internal (in which case make sure it is enabled and non-zero) or external (in which case make sure you are applying an appropriate reference voltage. –  Fred Hamilton Feb 22 '13 at 1:57
Something to check is that you've got Avss and Avdd connected, you need that even though you're using Vdd as the reference. –  PeterJ Feb 22 '13 at 2:01
I had AVdd connected to 3.3V and AVss to GND already. Hardware-wise, I think there shouldn't be a problem. –  Jack Feb 22 '13 at 18:07

I found out the problem was that my reference was not set correctly in the OpenADC() function. I needed ADC_REF_VDD_VSS instead of ADC_VREFPLUS_VDD. Here is the correct way to read an A/D value. This part goes inside the while(1) loop shown in the question.

// Constraints: A/D acquisition time must be >= 2.4 us (data sheet p264, Equation 20-3), conversion time (Tad) must be >= 0.7 us (data sheet p385, Table 26-26)
// Given that our Fosc = 4 MHz, which means Tosc = 1/Fosc = 1/4 MHz = 0.25 us,
// we must have at least 4 * Tosc = 1 us of conversion time (Tad).
// This is why we choose ADC_FOSC_4.
// Since Tad = 1 us, and we need a minimum acquisition time of of 2.4 us,