I'm trying to read a value from a PIC18f45k20 ADC but I always get a zero. It has to be my config that is wrong but I can't see where. I've checked the data sheet and googled (lots of conflicting info though...).
Details
- PIC18f45k20
- 16 Mhz crystal, PLL=4 so 64Mhz
- Input on AN11/RB4
- XC8
- Reading input from a LDR acting as a voltage divider from +3.3V. (I've confirmed with a multi-meter that this generates voltages around 1.5v-3v depending on light levels)
What I've tried to ensure is
- TRISB for RB4 is input
- ANSEL for ANS11 is analogue
- Channel 11 is selected
- Using Vdd and Vss as references rather than external refs
- Appropriate TAD and speed - I hope this is correct. Fosc/64, 20 TAD
I've checked the ADC checklist (data sheet 19.2.9) and as far as I can see everything is correct. I've also tried without using the XC8 ADC.h functions (i.e. just setting the bits) and I get exactly the same result.
Any ideas?
///////////////////////////////////////////////////////////////////////////////
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
//more setting here...//////////////////////////////////////////////////////////////////////////////
#define _XTAL_FREQ 64000000
#define _CLOCK_FREQ 16000000 // xtal / 4
int main(int argc, char** argv)
{
TRISA = 0b00000000;
TRISB = 0b00010000;
TRISC = 0b00000000;
CM2CON0 = 0;
CM2CON1 = 0;
CVRCON = 0x0;
ADCON0bits.CHS = 11;
ANSELHbits.ANS11 = 1;
ADCON1 = 0b00000000; // 00 = unimplemented, 0 = V- is Vss, 0 = V+ is Vdd, 0000 = unimplemented
ADCON2 = 0b00111110; // 0 = left justified, 0 = unimplemented, 111 = 20 TAD, 110 = Fosc/64
ADCON0 = 0b00101101; // 00 = unimplemented, 1011 = AN11, 0 = GO/DONE, 1 = ADON
while(1)
{
ConvertADC();
while(BusyADC())
{
}
int r = ReadADC();
delay(500);
}
return (EXIT_SUCCESS);
}
void delay( int ms )
{
while( ms > 0 )
{
__delay_ms(1);
--ms;
}
}
EDIT- 2014/06/14: I can get the ADC to work on a PIC18f4550 without much trouble. The code is equivalent but I still cant get the 45k20 working.
ADC on AN0/RA0. Based on the example from http://www.pic18f.com/uncategorized/2010/07/06/tutorial-5-ad-conversion-in-c/
TRISA = 0b00000001;
TRISD = 0b00000000;
ADCON1 = 0b00001110;//VSS,VDD ref. AN0 analog only
ADCON0 = 0x00;//clear ADCON0 to select channel 0 (AN0)
ADCON2 = 0b00001000;//ADCON2 setup: Left justified, Tacq=2Tad, Tad=2*Tosc (or Fosc/2)
ADCON0bits.ADON = 0x01;//Enable A/D module
LATDbits.LATD0 = 1;
while(1)
{
ADCON0bits.GO_DONE = 1;//Start A/D Conversion
while(ADCON0bits.GO_DONE != 0);//Loop here until A/D conversion completes
unsigned short r = ADRES;
LATDbits.LD0 = r == last ? 0 : 1;
last = r;
delay(100);
}