切换到宽版
  • 18981阅读
  • 45回复

关于单片机AD电压电流采样的软件滤波快被整疯了 [复制链接]

上一主题 下一主题
离线kreina

发帖
3527
M币
9830
专家
99
粉丝
229
只看该作者 10楼 发表于: 2017-07-16
看你这个板子的布局,我感觉还是重新来一遍效果比较实在
本帖最近打赏记录:共1条打赏M币+5
离线junyee

发帖
3755
M币
791
专家
9
粉丝
136
只看该作者 11楼 发表于: 2017-07-16
回 wanjinjie 的帖子
wanjinjie:1.STC15自带的是10位ADC,所以如果你用的是片内ADC那么你需要定义int型变量按照10bit来采样处理!
2.采样10次去掉最大最小值然后向右移位三次就好了
3.计算电压的时候的小数点要放大后在计算,这种单片机尽量不要计算浮点数
参考我的例子带详细中文注释的电压采样http://bbs.mydig .. (2017-07-15 21:26) 回 wanjinjie 的帖子

在这里也看见你了.


对你的提出的三点也说点自己的看法.

1: 楼主说清楚了他用的是外部ADC,而且是8位的,所以用 8位变量来存储没有错.而其累加值已经用了 16位变量.
2: 楼主用的已经是去最大去最小,除以8, 一般编译器对 除数 2/4/8/... 之类的乘除法会优化为移位运算的.
3: 浮点运算要占用单片机大量的的时钟周期, 但楼主没有提供完整的代码,也不知道他是不是这样做.

-------------
#建议楼主在以前一次的回复中完善程序.

1: 程序采集ADC做一下判断,比如采集到异常数据,直接扔掉.
2: 不同宽度类型的变量运算一定要加强制转换!
3: 10#朋友说的,PCB布线有影响, 但也不至于 从10V跳到4V(除非你的电压源阻抗异常高). 而且就算PCB布线的再好,单片机/供电源的跳变无法忽视,一般有 数个LSB都属正常.
4: 另看你的代码,仍有优化空间.
本帖最近打赏记录:共1条打赏M币+5
离线junyee

发帖
3755
M币
791
专家
9
粉丝
136
只看该作者 12楼 发表于: 2017-07-16
回 junyee 的帖子
junyee:建议用 uart 来调试.
像你这种 从 12V跳到 4.XV ,波动太大了,应该是 运算溢出,或者采样到错误的数据. (2017-07-15 20:06) 回 junyee 的帖子

运算溢出是指 数学/逻辑操作 导致的溢出.
尤其是把多个运算写成一行时极易不小心出错.
如:

uint16_t a = 1024;
uint8_t b;

b = a * 80 / 512  ;

甚至常数都要小心, 印象中有的IDE 默认常数是16位的,
如果超出的话最好后面加个L.如:

uint32_t  c = 123456L ;

本帖最近打赏记录:共1条打赏M币+5
离线小白大白

发帖
241
M币
373
专家
2
粉丝
11
只看该作者 13楼 发表于: 2017-07-16
慢慢折腾吧,折腾好了就说明你搞懂了,哈哈。
本帖最近打赏记录:共1条打赏M币+5
离线wanjinjie

发帖
201
M币
176
专家
2
粉丝
10
只看该作者 14楼 发表于: 2017-07-16
回 junyee 的帖子
junyee:在这里也看见你了.
对你的提出的三点也说点自己的看法.
....... (2017-07-16 06:41) 回 junyee 的帖子

看来您也是高手一枚啊!因为现在不确定是采集的数据出问题了还是在计算的过程出问题了!所以可以从几个方面去处理!1.在现在的中位值平均滤波的基础上加入限幅滤波法,去除偶然的异常采集的数据,2.在采集数据的计算时出现数据溢出或计算错误,3.我在调试ADC电压表的时候的做法是低速采集ADC数据,然后将采集到的ADC数据10个以及滤波好的数据和计算好的电压数据直接串口传到电脑,这样就能知道到底数据出错在什么地方,欢迎大家探讨
本帖最近打赏记录:共1条打赏M币+5
离线qiang7260

发帖
271
M币
1723
专家
2
粉丝
10
只看该作者 15楼 发表于: 2017-07-16
AD_And_Filter( AD_ch){
      uint8_t i = 0,j = 0,count=0;
      unsigned short min = 0 ,sum=0;
      for(i = 0;i < AD_SAMP_SIZE;i++){  //ADC采样的临时存放数组
      AD_Temp_Array = ADC_Process(AD_ch); //对输入端电压进行AD采样
      }
      for(i = 0;i < AD_SAMP_SIZE;i++){
          for(j = i + 1;j <SAMP_SIZE;j++){
              if(AD_Temp_Array > AD_Temp_Array[j]){
                  min = AD_Temp_Array[j];
                  AD_Temp_Array[j] = AD_Temp_Array;
                  AD_Temp_Array = min;
              }
          }
      }

      for(count=1;count<SAMP_SIZE-1;count++) //连续采样N个数据,去掉一个最大值和一个最小值
      sum += AD_Temp_Array[count];
      return sum/(SAMP_SIZE-2);  //然后计算N-2个数据的算术平均值      
我用这个很好用,注释清楚,觉得可以支持一下。
本帖最近打赏记录:共1条打赏M币+5
离线junyee

发帖
3755
M币
791
专家
9
粉丝
136
只看该作者 16楼 发表于: 2017-07-16
伸手党,来吧~~~




本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共1条打赏M币+5
离线2545889167

发帖
12139
M币
9527
专家
275
粉丝
4640
只看该作者 17楼 发表于: 2017-07-16
个人感觉问题在硬件上的可能性要更大一点
本帖最近打赏记录:共1条打赏M币+5

发帖
18
M币
799
专家
4
粉丝
3
只看该作者 18楼 发表于: 2017-07-16
楼主有没有试过递推中位值滤波法
本帖最近打赏记录:共1条打赏M币+5
离线指挥

发帖
57
M币
79
专家
1
粉丝
3
只看该作者 19楼 发表于: 2017-07-16
我倒是怀疑电源可能有问题,是不是设置过流了
本帖最近打赏记录:共1条打赏M币+5
快速回复
限80 字节
温馨提示:欢迎交流讨论,请勿发布纯表情、纯引用等灌水帖子;以免被删除
 
上一个 下一个