Conversión de ADC PIC18F4520 en MC18

tengo un dilema

Necesito leer los valores de ADC de PIC18F4520 . Mi configuración y código es el siguiente:

#define OSC INTIO67
int adc_result = 0;

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;

    OpenADC( ADC_FOSC_32      &
         ADC_RIGHT_JUST   &
         ADC_4_TAD,
         ADC_CH0          &
         ADC_REF_VDD_VSS  &
         ADC_INT_OFF, ADC_5ANA);

    while (1) {
        SetChanADC(ADC_CH0);
        ConvertADC();
        while (BusyADC());
        adc_result = ReadADC();
    }
    CloseADC();
}

El asunto es este:

  1. Cuando lo ejecuto en MPLAB v8.x, mi lectura está ligeramente apagada y finaliza mi depuración.
  2. No puedo volver a depurar el PIC porque recibo errores como "No se puede ingresar al modo de depuración".

¿Cómo soluciono esos problemas? Además, ¿es correcta mi configuración de ADC (dado que ADC requiere un reloj para realizar la conversión de ADC) con mi reloj interno? ¿Es correcto configurar la señal del reloj a 32 MHz?

Estoy programando usando PicKit2 (con el botón negro).

Solo para aclarar: ¿está depurando un dispositivo real o lo está simulando? ¿Está incluyendo el encabezado correcto para el dispositivo (no se muestra en su código)?
Estoy depurando un dispositivo real. Solo he configurado WDTa OFFy LVPa OFF. Mis incluye son 18f4520.h, así como adc.h.

Respuestas (1)

No está configurando la señal de reloj del ADC a 32MHz. El parámetro ADC_FOSC_32divide el reloj por 32 (consulte la página 225 de la hoja de datos ). Esto asegura, junto con los bits de selección de tiempo de adquisición ( ADC_4_TADen su caso), el tiempo mínimo (/máximo) de adquisición A/D (ver página 359). Cuando daña estos requisitos, no obtendrá resultados válidos/precisos.

Con las ecuaciones dadas en la página 228, puede hacer los cálculos y verificar que se cumplan los requisitos.

Algunos otros puntos:

  • En su código, nunca inicia la conversión de ADC llamando a ConvertADC.
  • Está configurando el puerto acomo salida mediante la configuración TRISA = 0x0;, pero desea que se configure como entrada (como dice su comentario). TRISA = 0xFF;configuraría todos los pines en el puerto a como entrada.


Para ampliar un poco el tiempo de aquisición ( T A D ): Este tiempo es necesario para que el circuito interno probablemente se cargue. Cuando este tiempo es demasiado corto, no obtendrá resultados o obtendrá malos resultados.

Para 32Mhz (sin divisor) T A D serían 31 ns. Eso es demasiado rápido. Se requieren al menos 0.7us para que el ADC funcione probablemente. Así que seleccionas un divisor adecuado para obtener T A D por encima de 0.7us. Un divisor de 32 lo hará aquí, T A D = 1 nosotros > 0.7us.

Gracias, entonces, ¿cómo configuro la señal de reloj de ADC Fosc(en este caso, 32Mhz)? Además, lo tengo ConvertADC(), fue un error tipográfico. Lo siento.
De nuevo: hay que verificar que el tiempo de aquisición ( T A D ) se cumple. En la página 359 verás el mínimo T A D es 0.7us. Entonces, para una frecuencia de oscilador más alta, debe seleccionar un divisor más grande. La tabla 19-1 le dará una visión general. Le recomendaría que lea la hoja de datos , al menos la sección 19, ADC.