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);
}
Best Answer
I don't like "fix my code" too :) I will not analyse your code, I'm not PIC expert, I just started with Microchip microcontrollers - they are awesome! :)
Edited:
So this is how I do it on
PIC18F4550PIC18F25k50 and it works for sure.It should work on PIC18F4520 too.End of edited.
You have to change port and probably voltage reference configuration.
Im using XC8 too. Code is not complete, this is just ADC part.