Problemas con la conversión PIC A/D

Estoy tratando de leer la señal analógica para una especie de mouse con un controlador pic18f14k50. Aquí el circuito simple: http://dl.dropbox.com/u/14663091/schematiconew.pdf . Tengo que leer la señal analógica del puerto del circuito AN9. La función principal lee desde el puerto y parpadea 30 veces si se alcanza el umbral:

void main(void) 
{
    InitializeSystem();

    #if defined(USB_INTERRUPT)
        USBDeviceAttach();
    #endif

    while(1) {

        if ((USBDeviceState < CONFIGURED_STATE) || (USBSuspendControl == 1)) continue;

        if (!HIDTxHandleBusy(lastTransmission)) {
            int readed = myReadADC2(); //Here i tried both myReadADC2() or myReadADC1()
            if (readed > 40) { //If read threshold > 40, blink led 30 times
                int i;
                for (i = 0; i < 30; i++) {
                    Delay1KTCYx(0);
                    mLED_1_On();
                    Delay1KTCYx(0);
                    mLED_1_Off();
                }
            }
        lastTransmission = HIDTxPacket(HID_EP, (BYTE*)hid_report_in, 0x03);

        } /* [Ed: added] */
    }//end while
}//end main

Usé dos métodos para leer desde el puerto AN9, myReadADC() que usa el método API OpenADC():

int myReadADC(void) 
{
    #define ADC_REF_VDD_VDD_X 0b11110011                      
    OpenADC(ADC_FOSC_RC & ADC_RIGHT_JUST & ADC_12_TAD,
            ADC_CH9 & ADC_INT_OFF,
            ADC_REF_VDD_VDD_X & ADC_REF_VDD_VSS,
            0b00000010); // channel 9
    SetChanADC(ADC_CH9);
    ConvertADC();                 // Start conversion
    while (BusyADC());             // Wait for completion
    return ReadADC();           // Read result
}

y myReadADC2(), que implementa la lectura manual desde el puerto.

int myReadADC2() 
{
    int iRet;
    OSCCON = 0x70;         // Select 16 MHz internal clock
    ANSEL = 0b00000010;  // Set PORT AN9 to analog input
    ANSELH = 0;          // Set other PORTS as Digital I/O
    /* Init ADC */
    ADCON0 = 0b00100101;   // ADC port channel 9 (AN9), Enable ADC
    ADCON1 = 0b00000000;   // Use Internal Voltage Reference (Vdd and Vss)
    ADCON2 = 0b10101011;   // Right justify result, 12 TAD, Select the FRC for 16 MHz
    iRet = 100;


    ADCON0bits.GO = 1;
    while (ADCON0bits.GO);   // Wait conversion done
    iRet = ADRESL;           // Get the 8 bit LSB result
    iRet += (ADRESH << 8); // Get the 2 bit MSB result
    return iRet; 
}

Ambos casos no funcionan, toco (enviando señal analógica) el puerto AN9 pero cuando configuro el umbral alto (~50) el led no parpadea, con el umbral bajo (~0) parpadea inmediatamente cuando le doy energía al PIC. ¿Quizás estoy usando un puerto incorrecto? ¿En realidad estoy pasando AN9 como puerto de lectura? ¿O tal vez el umbral está mal? ¿Cómo puedo encontrar el valor correcto? Gracias

Aquí el MPLAB C18 Apis http://dl.dropbox.com/u/14663091/API%20microchip%20C18.pdf .

No puedo acceder a Dropbox donde estoy ahora, pero sé que una cosa que me fastidió fue asegurarme de que estaba usando un pullup o pulldown... ¿has comprobado eso? (Puede que no sea su código real lo que está causando el problema, pero esto es solo una especulación)
¿Alguna vez solucionaste esto?
Y ahora el enlace está muerto. Es por eso que no usamos Dropbox.

Respuestas (4)

Creo que hay un error en su myReadADC2() sub...

intente devolver iRet; en lugar de devolver iDelay;

Lo sentimos, el código real es correcto, solo fue un error tipográfico.

El PIC ADC tiene una impedancia de entrada sorprendentemente baja. No estoy seguro de que tocar la entrada vaya a funcionar bien. La mayoría de las veces, necesitará un amplificador operacional para almacenar la señal en el PIC, a menos que su señal sea naturalmente de baja impedancia.

Lea atentamente la hoja de datos. Sería bueno si las hojas de datos pusieran limitaciones conocidas y errores en letra grande y negrita, pero generalmente están ocultos en notas al pie y tablas de características eléctricas.

Esta ha sido mi experiencia también. Especialmente cierto para muchos de los multiplexores analógicos integrados en los PIC.

Agregue un conector para ICSP/depuración y use un PICkit o ICD 3 para depurar su código. Luego puede concentrarse en hacer que el ADC funcione y luego ordenar el código USB.

Encontrará las cosas mucho más fáciles si utiliza el código ADC de Microchip en sus bibliotecas.

Su esquema parece indicar que nada está conectado al pin 9, que resulta ser AN9.

¿Podría, al menos temporalmente, poner un botón con una resistencia pull-up, idéntica a la que ya tiene en el pin 5, para que sepamos que el pin en realidad se está tirando hacia arriba y hacia abajo?