单片机ADC采样算法----递推平均值采样法

       在上一篇文章单片机ADC采样算法---平均值采样法中分析了平均值采样法的使用,上篇文章中的平均值采样法是连续采样100个数据,然后求平均值,这种方法存在一个问题,就是采集100个值之后,下一次又重新采集100个新的值,这两次采集的值是不连续的,相当于每次都是独立的采集来100个值,然后求平均值。这样计算出来的值有可能看不出来数据的变化趋势。希望在求平均值的时候每次读取到一个新的值,就将最早读取的旧值丢弃一个,相当于水管中的流水一样,有新的水流进来,就让最早进来的水流出去。这样采集到的数据就是连续变化的。这样通过采样值就能看出来采样数据是否发生了波动。

    算法如下:

#define N 100
unsigned int filter4( void )                   
{
    static unsigned int value_buf[N];
    static unsigned int i = 0;
    unsigned int count;
    int  sum = 0;
    value_buf[i++] = ReadVol_CH3();
    if( i == N )
    {
        i = 0;
    }
    for( count = 0; count < N; count++ )
    {
        sum += value_buf[count];
    }
    return ( unsigned int )( sum / N );
}

           通过数组将采样的数据存储起来,若数组存满之后,数组下标直接跳转到数组头,覆盖最早采样的数据。然后再计算平均值 。但是用数组存储的话会浪费单片机大量的存储空间,如果采样的数据比较多,单片机的空间有可能不够用。所以为了节省单片机的空间,这里不用数组存储,而是用另一种方法来实现  。

        改进后的算法如下:

#define CNT  100
u16 get_ave( void )
{
    static  u8 count = 0;
    static  u32 S = 0;      //累加和
    static  u16 C = 0;      //本次采样值
    static  u16 A = 0;      //平均值
    C = ReadVol_CH3();
    if( count == 0 )
    {
        A = C;
        S = A * CNT;
        count = 1;
    }
    S = S - A + C;              //加上本次采样值,减去上次平均值
    A = S / N;                  //计算本次平均值
    return A;
}

      不用数组存储的话就不知道最早采样的值是多少,这里用上次采样的平均值代替最早的采样值。A代表上次采样的平均值,C代表本次采样的值,S代表100次数据的累加和,每次采样到新数据时,就用累加和减去上一次的平均值,然后再加上本次采样的值,计算出本次采样新的平均值。

   这样S就相当于连续100个数据的累加和,每次有新的数据进来之后,先减去旧的数据,再加上新的数据。这样计算出来的平均值就是连续的。下来测试一下优化算法。

 

这是函数发生器产的一个100HZ的正弦波,最小值是0V,最大值是4V,平均值是2.02V。单片机通过串口将采样回来的平均值发送出来,用串口波形显示软件,将采样值的波形显示出来。

通过串口波形软件可以看出,采样回来的值是波动的,说明优化后的采样算法更能实时的反应出来采样波形的波动情况。

在波形显示软件右下角可以看到,采样回来的值最小是419,最大是427,单片机ADC是10位分辨率 2^10=1024,所以采样的平均电压为 419/1024*5=2.0458984375V         427/1024*5=2.0849609375V  采样的平均值在2.04和2.08V之间波动。和示波器测出来的平均值2.02V有一点误差,误差最大值为0.06V左右,上一篇平均值采样法的最大误差为0.02V。

    改进后的平均值采样算法和上一篇单片机ADC采样算法---平均值采样法采样的值相比,误差增大了,但是相对于平均值采样法来看,采样的值能更快速的反应出采样数据的变化情况。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值