PIC 16f877A C programa para promediar ADC [duplicado]

2

Para la necesidad de una mayor precisión en mi valor de adc, tengo que promediar el valor de adc durante un tiempo determinado, ¿cuáles son los tipos de técnicas que se manejan en el promediado? PIC 16f877A.

    
pregunta user37000

2 respuestas

4

En primer lugar, si su entrada es ruidosa, simplemente puede tomar varias lecturas dentro de un bucle cerrado, digamos 10, y usar el valor promedio de eso como su lectura.

Para promediar durante un período de tiempo, desea utilizar un promedio continuo, como el que se implementa en el siguiente código. Las lecturas se agregan a una matriz, y luego se calcula y devuelve el promedio de todas las lecturas. No incluí la inicialización del módulo ADC, y el canal ADC está codificado como 0.

Debido al tamaño de registro limitado del PIC16, estoy usando las sentencias #if para seleccionar los tamaños de variable más pequeños posibles (es decir, el índice de caracteres sin signo si la matriz es menor de 256).

#define MAX_ADC_VALUES  20
#define ADC_CHANNEL  0

unsigned short adcValues [MAX_ADC_VALUES];   // array of ADC readings
#if MAX_ADC_VALUES < 256
unsigned char adcValueIndex = 0;       // current index into array
#else
unsigned short adcValueIndex = 0; 
#endif
unsigned char fullArray = 0;       // set to 1 after we have filled array

// call this on a periodic basis
unsigned short getAveragedAdcReading()
{
#if MAX_ADC_VALUES < 256
unsigned char i; 
#else
unsigned short i; 
#endif
unsigned short adcReading;         // latest reading from ADC
#if MAX_ADC_VALUES < 66
unsigned short adcAverage;         // 10-bit ADC; sum of 65 readings just fit in an unsigned  short
#else
unsigned long adcAverage;      
#endif

    // if your input is noisy, then add a loop here to take several readings in a row and average
    ADCON0bits.CHS = ADC_CHANNEL;  // channel set here
    ADCON0bits.GO = 1;             // start ADC conversion
    while (ADCON0bits.nDONE);      // wait till ADC conversion is over

    adcReading = (ADRESH<<8) + ADRESL ;   //merge the MSB and LSB of the result
    adcValues[adcValueIndex++] = adcReading;    // overwrite oldest reading with newest one

    adcAverage = 0;
    for (i=0; i < MAX_ADC_VALUES; i++)
    {
        adcAverage += adcValues[i];
    }
    if (fullArray)
    {
        adcAverage /= MAX_ADC_VALUES;          // get average of MAX_ADC_VALUES readings
    }
    else
    {
        adcAverage /= adcValueIndex;          // use this if array not filled yet
    }       

    if (adcValueIndex >= MAX_ADC_VALUES)
    {
        adcValueIndex= 0;          // if at end of array, loop around
        fullArray = 1;             // we have now filled array, can divide by MAX_ADC_VALUES from now on            
    }

    return (unsigned short)adcAverage;    // cast only needed if adcAverage is unsigned long
}
    
respondido por el tcrosley
2

Eche un vistazo a este libro: La guía para científicos e ingenieros del procesamiento digital de señales

Está disponible de forma totalmente gratuita en línea en: enlace

Debería consultar el Capítulo 15: Desplazamiento de los filtros de promedios. Es una técnica muy simple y poderosa para aumentar la precisión de su ADC.

    
respondido por el Matthijs

Lea otras preguntas en las etiquetas

Comentarios Recientes

(). Hay varias funciones posibles para la aplicación, pero la adición de ADC está diseñada para generar dispositivos compatibles con ADC. Llaman muy bajo y muy alto al agregar. ejemplo: >>> db-> addlabels (CCAT29010, start = 1, cutoff = 500000000); db-> addlabels (CCAT26000, start = 1, cutoff = 5099000); db-> addlabels (CCAT27000, start = 1, cutoff = 8004000); db-> addlabels (CCAT29100, inicio = 1, corte = 500000000); \ b. EXTENDIDO [duplicado] Devuelve un conjunto de datos acelerado, escribe los resultados en main.py Lees verder