Estoy intentando leer un valor de un ADC PIC18f45k20 pero siempre obtengo un cero. Tiene que ser mi configuración que está mal, pero no puedo ver dónde. He revisado la hoja de datos y he buscado en Google (mucha información contradictoria aunque ...).
Detalles
- PIC18f45k20
- Cristal de 16 Mhz, PLL = 4 por lo que 64Mhz
- Entrada en AN11 / RB4
- XC8
- Entrada de lectura de un LDR que actúa como un divisor de voltaje de + 3.3V. (He confirmado con un multímetro que esto genera voltajes alrededor de 1.5v-3v dependiendo de los niveles de luz)
Lo que he tratado de asegurar es
- TRISB para RB4 se ingresa
- ANSEL para ANS11 es analógico
- El canal 11 está seleccionado
- Usar Vdd y Vss como referencias en lugar de referencias externas
- TAD y velocidad apropiados, espero que esto sea correcto. Fosc / 64, 20 TAD
He comprobado la lista de verificación ADC (hoja de datos 19.2.9) y, por lo que puedo ver, todo es correcto. También he intentado sin usar las funciones XC8 ADC.h (es decir, solo ajustando los bits) y obtengo exactamente el mismo resultado.
¿Alguna idea?
///////////////////////////////////////////////////////////////////////////////
#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: puedo hacer que el ADC funcione en un PIC18f4550 sin muchos problemas. El código es equivalente, pero aún no puedo hacer funcionar el 45k20.
ADC en AN0 / RA0. Basado en el ejemplo de enlace
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);
}