读取 ADC 值的浮动平均值

Floating average with reading of ADC values

我想做移动平均线或类似的东西,因为我从 ADC 得到嘈杂的值,这是我的第一次尝试,只是为了计算移动平均线,但值每次都变为 0,你能帮我吗?

这是代码的一部分,它使这个神奇:

unsigned char buffer[5];
    int samples = 0;
    USART_Init0(MYUBRR);
    uint16_t adc_result0, adc_result1;
    float ADCaverage = 0;

    while(1)
    {

        adc_result0 = adc_read(0);      // read adc value at PA0
        samples++;
        //adc_result1 = adc_read(1);      // read adc value at PA1

        ADCaverage = (ADCaverage + adc_result0)/samples;

        sprintf(buffer, "%d\n", (int)ADCaverage); 
        char * p = buffer;
        while (*p) { USART_Transmit0(*p++); }
        _delay_ms(1000);
    }
    return(0);
}

我通过 usart 发送这个结果以显示值。

你的等式不正确。

s_n = (sum_{i=0}^{n} x[i])/n则:

s_(n-1) = sum_{i=0}^{n-1} x[i])/(n-1)

sum_{i=0}^{n-1} x[i] = (n-1)*s_(n-1)
sum_{i=0}^{n} x[i] = n*s_n


sum_{i=0}^{n} x[i] = sum_{i=0}^{n-1} x[i] + x[n]

n*s_n = (n-1)*s_(n-1) + x[n] =  n*s_(n-1) + (x[n]-s_(n-1))
s_n = s_(n-1) + (x[n]-s_(n-1))/n

你必须使用

ADCaverage += (adc_result0-ADCaverage)/samples; 

您可以使用只需要 1 个内存单元的指数移动平均线。
y[0] = (x[0] + y[-1] * (a-1) )/a
其中 a 是过滤因子。

如果 a 是 2 的倍数,您可以使用轮班并显着优化速度:
y[0] = ( x[0] + ( ( y[-1] << a ) - y[-1] ) ) >> a

这对左对齐的 ADC 尤其有效。关注移位结果的字长即可。