Portando código MikroC a MPLAB para PIC16F1508 agregando ruido adicional a ADC

1

Decidí comenzar a usar MPLAB con XC8 después de haber comenzado a alcanzar el límite de tamaño de código de 2k en MikroC. El problema es que, como todas las bibliotecas Mikroc son propietarias y no hay bibliotecas disponibles para la serie PIC16F en MPLAB, tuve que escribir mis propias funciones ADC.

Estas son las dos funciones que escribí para configurar mi ADC usando la hoja de datos:

void ADC_Init(){
    PIR1bits.ADIF = 0; // Clear interrupt flag
    PIE1bits.ADIE = 0; // Disable ADC interrupt
    INTCONbits.PEIE = 0; // Disable perriferal interrupts

    ADCON2 = 0; // No ADC Trigger

    ADCON1bits.ADCS = 0b111; // Select internal RC clock source
    ADCON1bits.ADPREF = 0b00; // Select VDD as Vref
    ADCON1bits.ADFM = 0; // Left justify, upper 8 MSB in ADRESH

    ADCON0bits.ADON = 1; // Turn on ADC Module
}

int ADC_Read(char channel){
    ADCON0bits.CHS = channel; // Set channel, must be between 0 and 11
    __delay_us(5); // Wait some arbitrary acquisiton time

    PIR1bits.ADIF = 0; // Clear interrupt flag
    ADCON0bits.GO_nDONE = 1; // Start acquisioin

    while(ADCON0bits.GO_nDONE) {} // Wait for the conversion to finish

    return (ADRESH << 2) | ADRESL;

}

Para empezar, la señal de entrada que estoy leyendo es bastante ruidosa. En mi programa MikroC con las funciones de biblioteca ADC, el nivel mínimo de ruido en las muestras osciló entre 60 y 100 (ADC de 10 bits). Por piso de ruido, me refiero al rango de valores que el ADC estaba leyendo sin entrada. El ruido del resto del sistema supongo.

En MPLAB con las funciones anteriores, el piso de ruido se ha disparado entre 200 y 300. En un ADC de 10 bits, este ruido es inaceptable. Ejecuto la función ADC_Init () una vez fuera de mi ciclo de programa principal, luego uso la función ADC_Read (..) en mi programa.

¿Alguna idea sobre por qué el ruido es mucho más? ¿O alguna idea sobre cómo MikroC obtiene este rendimiento? Sospecho que tiene algo que ver con la forma en que configuré el ADC.

EDITAR

En respuesta a la respuesta de Olin, creo que el "tiempo de adquisición" 5us podría ser un nombre inapropiado, ese retraso está ahí para permitir que el capacitor de retención se cargue después de cambiar los canales ADC. La hoja de datos muestra un ejemplo de una impedancia de señal de 10kohm que requiere un tiempo de carga de 7.4us. Mi impedancia de señal es de solo 700 ohmios, por lo que pensé que los 5 deberíamos ser más que suficientes. En cuanto al circuito, no ha cambiado, solo el software lo ha hecho. Y la señal que estoy midiendo es una señal digital ligeramente ruidosa que sale de un IC de filtro MSGEQ7.

    
pregunta Shubham

2 respuestas

4

Esta es una buena ilustración de los problemas que surgen al usar bibliotecas enlatadas.

Si originalmente tenía un 10% de ruido en la señal, tal vez el problema esté en el circuito. ¿Qué tipo de señal estás midiendo? ¿Cuál es su frecuencia superior? ¿Con qué frecuencia estás tomando muestras? Sería útil mostrar el esquema.

Parece que estás permitiendo 5 µs para la adquisición, pero ¿cómo sabes que es suficiente? ¿Qué impedancia está alimentando la señal al A / D? Una posible explicación de sus síntomas es que la impedancia de la señal es demasiado alta, y el código anterior utilizó un tiempo de adquisición más largo, lo que permitió que la muestra y la retención se asentaran más cerca del valor correcto.

Sin embargo, una mejor respuesta es probablemente repensar toda la estrategia A / D en primer lugar. No se base en qué rutinas de la biblioteca están disponibles o en algunas tonterías similares. Lea la sección de la hoja de datos en el A / D y piense en la mejor manera de usarla, posiblemente junto con otro hardware, como los temporizadores, para resolver el problema general de medición.

Una estrategia que utilizo a menudo es tomar lecturas A / D en una interrupción periódica. Ejecute esto tan rápido como el A / D le permitirá adquirir y convertir la señal, y dentro de los límites de dejar suficientes ciclos de primer plano para el resto del sistema. Esta interrupción A / D muestrea el A / D mucho más rápido de lo que realmente necesita, luego el paso bajo filtra los resultados. Cuando el código principal desea la última lectura, no sale y toma una sola lectura A / D. Solo utiliza el valor actual de la salida del filtro de paso bajo. He hecho este tipo de cosas muchas veces. De hecho, es mi forma normal de tomar lecturas A / D a menos que haya una razón específica para hacerlo de manera diferente.

En un pequeño microcontrolador, no hay sustituto para entender realmente el hardware y ser consciente de cómo se está utilizando exactamente, ya sea a través de su propio código o rutinas de "biblioteca".

Añadido sobre las interrupciones periódicas A / D

Ahora dice que está utilizando interrupciones periódicas para leer el A / D, pero entonces su código tiene aún menos sentido que antes. Si solo está leyendo un solo canal, entonces dejaría el A / D configurado en ese canal y no lo cambiaría durante la operación normal. Si está leyendo varios canales, la interrupción pasaría por ellos. En ese caso, la interrupción de conversión A / D hecha cambiaría el hardware al nuevo canal justo después de obtener los resultados de la conversión. De esa manera, la mayor parte del tiempo que no es conversión se usa para adquirir la siguiente señal. Incluso si tuviera que ejecutar el A / D bastante rápido, como 100 kHz, por ejemplo, eso deja la mayoría de 10 µs para la adquisición.

De todos modos, generalmente no llamaría a una rutina de conversión A / D desde una interrupción, e incluso si lo hiciera, no cambiaría el canal y luego esperaría la adquisición y conversión mientras el código de primer plano esté bloqueado del procesador. Eso no tiene sentido y es innecesario.

Luego está el problema de devolver el valor de 10 bits sin firmar justificado en un entero con signo. No tiene sentido que los valores de 512 y superiores se interpreten como negativos.

Una vez más, ¿cuál es el contenido de frecuencia superior de la señal? ¿Con qué frecuencia el firmware necesita su valor? Hago estas preguntas por buenas razones, y espero que las responda, ya sea que piense que son relevantes o que entienda las razones o no. Después de todo, este es tu problema. Somos voluntarios que intentamos ayudar, pero si se niega a cooperar, encontraremos otros lugares para pasar nuestro tiempo limitado aquí.

    
respondido por el Olin Lathrop
1

No hay nada inherente a ninguna de las bibliotecas que deba impactar el piso de ruido. El estado predeterminado para muchos PIC ADC es de 8 bits, y necesita configurar las cosas para obtener los 10 bits completos (no sé cómo se hace en MPLAB). Esto puede haber sido manejado por usted en MikroC. Además, debe asegurarse de que sus datos estén justificados correctamente en el entero de 16 bits. Si lo tiene justificado a la izquierda, y solía estar justificado a la derecha, su nivel de ruido parecería grande

    
respondido por el Scott Seidman

Lea otras preguntas en las etiquetas