在上一篇文章单片机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采样算法---平均值采样法采样的值相比,误差增大了,但是相对于平均值采样法来看,采样的值能更快速的反应出采样数据的变化情况。

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

  1. c语言adc采集取平均值,单片机ADC采样算法----递推平均值采样法

    在上一篇文章单片机ADC采样算法---平均值采样法中分析了平均值采样法的使用,上篇文章中的平均值采样法是连续采样100个数据,然后求平均值,这种方法存在一个问题,就是采集100个值之后,下一次又重新采 ...

  2. C 语言实现的滑动平均滤波算法,滑动平均滤波算法(递推平均滤波法)

    /// ///滑动平均滤波算法(递推平均滤波法) /// /// /// GN为数组value_buf[]的元素个数,该函数主要被调用,利用参数的数组传值 /// private const int ...

  3. 单片机ADC采样算法----加权递推平均滤波法

    加权递推平均滤波法是对递推平均滤波法的改进,即不同时刻的数据加以不同的权.通常是,越接近现时刻的数据,权取得越大.给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低. 下面直接看C代码的实现 d ...

  4. matlab如何仿真递推型dft算法,递推dft算法

    0.7 0.8 0.9 1 0.6 0.7 0.8 0.9 1 伯格(Burg)递推算法 L-D算法缺点: 在计算相关函数估计时,对N个观测数据以 外的数据作零的假设,故谱估计误差较...... 第3 ...

  5. 0x02.基本算法 — 递推与递归

    目录 一.递推与递归 二.分治 三.模拟计算机实现递归 四.相应习题: 0.AcWing 92. 递归实现指数型枚举(递归/循环+位运算) 1.AcWing 93. 递归实现组合型枚举 2.AcWin ...

  6. 基础算法 —— 递推算法

    [概述] 递推算法:通过已知条件,利用相邻的数据项间的关系(即:递推关系),得出中间推论,直至得到结果的算法. 递推关系:给定一个数的序列H0,H1,-,Hn,若存在整数N0,使当n>N0时,可 ...

  7. C/C++程序设计常用算法——递推法

    文档声明: 以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正.并且该文档在后期会随着学习的深入不断补充完善. 资料仅供学习交流使用. 作者:Aliven888 1.简述 ...

  8. 递推最小二乘遗忘因子法(Recursive Forgetting Factor, RFF)

    在普通的递推最小二乘算法中,随着数据的不断到来,显然矩阵XTXX^TXXTX中的元素会变得越来越大,而矩阵PkP_kPk​作为XTXX^TXXTX的逆矩阵,则会逐渐趋于零,这时,模型将无法继续更新或者 ...

  9. 用递推法和递归法计算一个数的阶乘

    递推法 #include<stdio.h> int main() {int n,y=1,i;scanf("%d",&n);if(n==0||n==1) y=1; ...

最新文章

  1. gitlab安装各种坑
  2. Springboot启动原理解析
  3. 2018 年度 GtiHub 开源项目 TOP 25:数据科学 机器学习
  4. springboot tomcat配置_告诉你,Spring Boot 真是个牛逼货!
  5. java 线程 Thread Runnable 实现样例
  6. 收藏 | YOLOX模型部署、优化及训练全过程
  7. SQLite 增删改查
  8. Hadoop Hbase 模型结构
  9. 小程序入门学习12--云函数与数据库01
  10. Rootkit之ntrootkit的配置使用
  11. lvremove 删除逻辑卷
  12. fedora14安装
  13. php微信 消息推送 配置,PHP微信公众号模板消息推送
  14. java opencv 模板匹配算法_opencv 模板匹配
  15. python之微博批量关注,互粉
  16. html转化pug,pug转化html,sass转化scss
  17. 纹理压缩格式DXT/PVR/ETC编码
  18. 我闺蜜她男朋友要我用Python写个脚本,每天不同时间段用微信给闺蜜发消息
  19. 图片报道:2008年12月4日夜,暴风雪突袭烟台(下)
  20. golang 万年历的实现代码

热门文章

  1. python 中字符串大小写转换
  2. 【HDU2825】Wireless Password【AC自动机,状态压缩DP】
  3. rabbitmq AmqpClient 使用Fanout 交换机投递与接收消息,C++代码示例
  4. 02--Tomcat总体结构分析一
  5. Caused by: java.lang.NoClassDefFoundError: net/sf/ezmorph/Morpher
  6. ListView上拉加载,下拉刷新 PullToRefresh的使用
  7. 什么是程序员的优良品质
  8. 【测试】软件测试分类体系系统学习
  9. 设计模式之单例模式8种实现方式,其五:懒汉式(线程不安全,同步代码块)
  10. apipost脚本使用二