找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8940|回复: 44
打印 上一主题 下一主题
收起左侧

单片机芯片读取ADC的值,数值在抖动,怎么办?

  [复制链接]
跳转到指定楼层
楼主
ID:1107043 发表于 2024-3-4 16:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位大佬。我现在遇到了个问题。我现在使用的是STM32G030单片机芯片。我需要读取一个引脚的ADC数值。我的期望是他可以比较稳定的在一个数值,波动范围小一点。现在结果发现数波动较。目前我使用了过滤采集的数值。即连续读取10个数,去2个最大2个最小,取剩下的平均值。可是还是不行。在暂时不改电路的基础上(即在采集ADC的线路加电阻电容过滤.),各位大佬教教我!
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1110945 发表于 2024-3-4 19:33 | 只看该作者
单片机的adc,都说是12位,其实能保证有效的精度只有8位,
好一点的能有10位有效精度,能到11位或以上精度的单片机非
常少。本来就是附加的功能,你的期望值不能太高。
你可以选择带16bit-adc功能的单片机呀,或者外加专门的adc芯
片。
回复

使用道具 举报

板凳
ID:1059013 发表于 2024-3-4 20:16 | 只看该作者
取样等待时间太短的原因吧
回复

使用道具 举报

地板
ID:883242 发表于 2024-3-4 20:29 | 只看该作者
那就多读几个数,直到满意为止。
回复

使用道具 举报

5#
ID:401564 发表于 2024-3-4 21:01 | 只看该作者
ADC引脚有个104的电容就行了,加太大电容影响"真实"数据
ADC的结果一定是抖动的,像万用表这种也是加了滤波的
在单片机上,平均值滤波是最常用的,它基本能解决大多数的应用
至少平均130次,然后再去掉最大和最小,数据位移一下,相对会好很多
10次就太少了
回复

使用道具 举报

6#
ID:453974 发表于 2024-3-5 09:09 | 只看该作者
增加读取时间,看看波动大不大,如果大的话考虑来个电容滤波
回复

使用道具 举报

7#
ID:41656 发表于 2024-3-5 11:28 | 只看该作者
没有电路不好判断。1、检查电源是否稳定是否有杂波,用示波器看看,G030的基准就是电源电源不稳定测量值自然会跳;2、检查是否切换通道,切换通道时候要预留足够的采样时间;3、检查前端电路是否稳定是否有噪声源;4、检查测量信号
回复

使用道具 举报

8#
ID:910742 发表于 2024-3-5 13:37 | 只看该作者
所谓波动大不知大到什么程度?g030的adc还是可以的,这是间隔0.1秒转换一次7号碱性电池的结果,可以参考下( 64Mhz,adc分频=2,采样时间=1.5,Vref直连Vdd)
1959
1958
1958
1959
1958
1958
1959
1959
1959
1958
1959
1958
1959
1960
1958
1959
1959
1958
1958
1958
1958
1959
1958
回复

使用道具 举报

9#
ID:1107043 发表于 2024-3-5 14:16 | 只看该作者
Y_G_G 发表于 2024-3-4 21:01
ADC引脚有个104的电容就行了,加太大电容影响"真实"数据
ADC的结果一定是抖动的,像万用表这种也是加了滤波 ...

很遗憾,均值滤波这个方法,我测试了一下没有区别,还是一样的波动
回复

使用道具 举报

10#
ID:1107043 发表于 2024-3-5 14:23 | 只看该作者
aidianzi 发表于 2024-3-5 11:28
没有电路不好判断。1、检查电源是否稳定是否有杂波,用示波器看看,G030的基准就是电源电源不稳定测量值自 ...

1,电源的话,已经使用滤波器测过了,很平稳。
2,这个芯片使用一个ADC,我采用的是连续转换,当一个通道装换结束了,自动切换到下一个通道转换。
3,噪音的话,有一个风扇,不过确实有一定的声音,但是我读取电源到芯片的却很稳定。
4,目前就是测量信号很不稳定,
回复

使用道具 举报

11#
无效楼层,该帖已经被删除
12#
ID:1048132 发表于 2024-3-5 15:40 | 只看该作者
多次采样然后取平均试试看
回复

使用道具 举报

13#
ID:1112216 发表于 2024-3-5 15:55 | 只看该作者
增加一级跟随器,减少采样对电压的影响
回复

使用道具 举报

14#
ID:401564 发表于 2024-3-5 16:20 | 只看该作者
c8t6 发表于 2024-3-5 14:16
很遗憾,均值滤波这个方法,我测试了一下没有区别,还是一样的波动



static u32 adc_sum = 0;
u16 adc_avg = 0;
adc_sum +=ADC的数字量;
adc_avg = adc_sum >> 5;
adc_sum -= adc_avg;
更改右移位数,就等于更改平均了,相对是比较平稳
但这好处也只是相对的,平均次数越多,反应也是越慢
回复

使用道具 举报

15#
ID:1112237 发表于 2024-3-5 18:40 | 只看该作者
取多组数值求平均值
回复

使用道具 举报

16#
ID:230500 发表于 2024-3-5 20:16 | 只看该作者
RC滤波不能省; 固定的一个稳定值是不可能的, 内部也是通过电容充放电逐次逼近式采集; 多采集几次,再取平均算法 ,程序上采集速度越慢越稳。
回复

使用道具 举报

17#
ID:1059013 发表于 2024-3-5 20:35 | 只看该作者
模拟电压本来就是量子化的,没有波动才不对
回复

使用道具 举报

18#
ID:1107043 发表于 2024-3-6 11:06 | 只看该作者
fishafish 发表于 2024-3-5 20:35
模拟电压本来就是量子化的,没有波动才不对

我了解,在理论上是无限趋向于稳定,有波动我也可以接受,但是他波动在忽高忽低的,而且偏差在+-20mv这我就有点难受了
回复

使用道具 举报

19#
ID:1107043 发表于 2024-3-6 11:08 | 只看该作者
lidawei1 发表于 2024-3-5 13:37
所谓波动大不知大到什么程度?g030的adc还是可以的,这是间隔0.1秒转换一次7号碱性电池的结果,可以参考下 ...

我的波动大约是在20mv上下偏移
1562
1542
1572
1564
1555,这些之类的波动
回复

使用道具 举报

20#
ID:1107043 发表于 2024-3-6 11:09 | 只看该作者
eddy123 发表于 2024-3-5 15:40
多次采样然后取平均试试看

目前就是这么测试的,还是有一些峰值的波动出现,不过还没有在期望之内
回复

使用道具 举报

21#
ID:1107043 发表于 2024-3-6 11:17 | 只看该作者
Y_G_G 发表于 2024-3-5 16:20
static u32 adc_sum = 0;
u16 adc_avg = 0;
adc_sum +=ADC的数字量;

有点不太了解这个原理
回复

使用道具 举报

22#
ID:401564 发表于 2024-3-6 12:50 | 只看该作者
c8t6 发表于 2024-3-6 11:17
有点不太了解这个原理

adc_sum +=ADC的数字量;//每次运算都是把ADC的数字量累加
adc_avg = adc_sum >> 5;//位移就是除法运算了,位移3位就是除以8,得到平均值
adc_sum -= adc_avg;//累加的这个变量每次都减去平均值,这样做是不会溢出,每次运算都有前面的数据参与
adc_avg 这个是最终的值
这个算法比先累加8次,再除以8,然后把累加变量清除,代码更简单,显示更平

回复

使用道具 举报

23#
ID:910742 发表于 2024-3-6 13:35 | 只看该作者
c8t6 发表于 2024-3-6 11:08
我的波动大约是在20mv上下偏移
1562
1542

波动这么大肯定不能靠滤波的方法解决,可以先检查一下电路是否有干扰,看看电源有没有问题,输入的线尽量短,或者先短路输入看看波动多少。
回复

使用道具 举报

24#
ID:170975 发表于 2024-3-6 15:23 | 只看该作者
很可能就原始信号的噪声吧。
回复

使用道具 举报

25#
ID:1107043 发表于 2024-3-6 16:44 | 只看该作者
Y_G_G 发表于 2024-3-6 12:50
adc_sum +=ADC的数字量;//每次运算都是把ADC的数字量累加
adc_avg = adc_sum >> 5;//位移就是除法运算了 ...

不用把他们先排序,然后在去最大最小值,然后除于个数么?
回复

使用道具 举报

26#
ID:1107043 发表于 2024-3-6 16:45 | 只看该作者
Y_G_G 发表于 2024-3-6 12:50
adc_sum +=ADC的数字量;//每次运算都是把ADC的数字量累加
adc_avg = adc_sum >> 5;//位移就是除法运算了 ...
  1. NUM_SAMPLES = 10;
  2. while (1)
  3.     {
  4.                         
  5.                 uint32_t adc_values1[NUM_SAMPLES]={0};
  6.                 uint32_t adc_values2[NUM_SAMPLES]={0};
  7.                 uint32_t sum1 = 0;
  8.                 uint32_t sum2 = 0;

  9.                 uint32_t ADC_num7 = 0;
  10.                 uint32_t ADC_num0 = 0;
  11.                
  12.                  // 采集十次ADC1和ADC2的值
  13.                 for (int i = 0; i < NUM_SAMPLES; i++)
  14.                 {
  15.                         uint32_t A0;
  16.                         uint32_t A7;

  17.                         // 采集ADC1的值
  18.                         HAL_ADC_Start(&hadc1);
  19.                         while (HAL_ADC_PollForConversion(&hadc1, 100) != HAL_OK);
  20.                         A0 = HAL_ADC_GetValue(&hadc1);    //调整
  21.                         adc_values1[i] = (A0*3000)/4096;
  22.                         
  23.                         
  24.                         // 采集ADC2的值
  25.                         HAL_ADC_Start(&hadc1);
  26.                         while (HAL_ADC_PollForConversion(&hadc1, 100) != HAL_OK);
  27.                         A7 = HAL_ADC_GetValue(&hadc1);                        //采集
  28.                         adc_values2[i] = (A7*3000)/4096;
  29.                         
  30.                 }
  31.                
  32.                
  33.                
  34.                 bubble_sort(adc_values1,NUM_SAMPLES);
  35.                 bubble_sort(adc_values2,NUM_SAMPLES);
  36.                
  37.                 // 去掉ADC1数组中的最大值和最小值
  38.                 for (int i = 3; i < NUM_SAMPLES - 4; i++) {
  39.                         sum1 += adc_values1[i];
  40.                 }

  41.                 // 去掉ADC2数组中的最大值和最小值
  42.                 for (int i = 3; i < NUM_SAMPLES - 4; i++) {
  43.                         sum2 += adc_values2[i];
  44.                 }
  45.                
  46.                 // 计算打印平均值
  47.                 ADC_num0 = sum1 /4;
  48.                 ADC_num7 = sum2 /4;
  49.                
  50.                
  51.                 printf("\n电位器数值:%d \r\n",ADC_num0);
  52.                 printf("ADC采集数值:%d \r\n",ADC_num7);
  53.                 }
复制代码
这是我目前的算法
回复

使用道具 举报

27#
ID:910742 发表于 2024-3-6 18:23 | 只看该作者
c8t6 发表于 2024-3-6 16:45
这是我目前的算法

真要滤波的话设置256过采样、右移位数8就行了,直接硬件256个数取平均,不需要什么算法。
不过觉得应该查查是哪里出现的波动,短路输入看看。
下面是输入短路后的情况,没有滤波,没有过采样。
0
1
1
1
2
0
1
1
1
0
0
0
0
0
1
0
0
0
0
0
0
0
1
回复

使用道具 举报

28#
ID:1059013 发表于 2024-3-6 21:06 | 只看该作者
明显分压电阻太大?一般2k不会
回复

使用道具 举报

29#
ID:401564 发表于 2024-3-6 23:21 | 只看该作者
c8t6 发表于 2024-3-6 16:44
不用把他们先排序,然后在去最大最小值,然后除于个数么?

电路没有很大的干扰,就不需要
我这个基本只用于电源电压和温度之类的ADC,之前也有过去掉两头的数值,但实际上没啥区别,为了代码简单,就不用去最大和最小了
回复

使用道具 举报

30#
ID:420836 发表于 2024-3-7 08:35 | 只看该作者
请先检查参考电压,确保电压源稳定且无噪声。
回复

使用道具 举报

31#
ID:1007896 发表于 2024-3-7 09:59 | 只看该作者
ADC来的数据变化太快,你可以用定时器每隔一段时间如100ms读取一次数据,然后再处理。
回复

使用道具 举报

32#
ID:1074206 发表于 2024-3-7 10:36 | 只看该作者
增加硬件滤波或者软件滤波,但是要考虑实施性
回复

使用道具 举报

33#
ID:1107043 发表于 2024-3-7 13:56 | 只看该作者
lidawei1 发表于 2024-3-6 18:23
真要滤波的话设置256过采样、右移位数8就行了,直接硬件256个数取平均,不需要什么算法。
不过觉得应该 ...

我这个运行步骤是
1;风扇启动把高压离子吹出来。进过钢网;
2;钢网采集离子,经过放大电路放大得到电压;
3;把得到的电压进行ADC转化;
4:通过ADC判断是否在范围,不在范围则改变PWM;
5:PWM改变高压的电压,从而也影响到钢网采集的离子:
回复

使用道具 举报

34#
ID:1107043 发表于 2024-3-7 13:58 | 只看该作者
kk17328 发表于 2024-3-7 10:36
增加硬件滤波或者软件滤波,但是要考虑实施性

后续的升级是需要的。现在第一版本,只要确保在范围内即可。大约是上下浮动10mv左右
回复

使用道具 举报

35#
ID:1107043 发表于 2024-3-7 13:59 | 只看该作者
Y_G_G 发表于 2024-3-6 23:21
电路没有很大的干扰,就不需要
我这个基本只用于电源电压和温度之类的ADC,之前也有过去掉两头的数值,但实 ...

我这个的话,我使用示波器查看查看了曲线,会有一小段的起伏不定的峰值
回复

使用道具 举报

36#
ID:1107043 发表于 2024-3-7 14:01 | 只看该作者
yaofuming 发表于 2024-3-7 09:59
ADC来的数据变化太快,你可以用定时器每隔一段时间如100ms读取一次数据,然后再处理。

尝试过了。我给了固定不变的值;读取的是比较稳定。但是在代码中去调节的话,就会有波动
回复

使用道具 举报

37#
ID:401564 发表于 2024-3-7 16:57 | 只看该作者
c8t6 发表于 2024-3-7 13:56
我这个运行步骤是
1;风扇启动把高压离子吹出来。进过钢网;
2;钢网采集离子,经过放大电路放大得到电 ...

感觉这东西就跟采集空气中的PM2.5一样,所采集到的数据是做不到非常稳定的值的,它本身就不是稳定的值
你可以尝试256次平均值看一下效果
回复

使用道具 举报

38#
ID:1107043 发表于 2024-3-8 08:22 | 只看该作者
Y_G_G 发表于 2024-3-7 16:57
感觉这东西就跟采集空气中的PM2.5一样,所采集到的数据是做不到非常稳定的值的,它本身就不是稳定的值
你 ...

好的。我尝试一下
回复

使用道具 举报

39#
ID:361553 发表于 2024-3-8 10:05 | 只看该作者
加运放
回复

使用道具 举报

40#
ID:828160 发表于 2024-3-8 15:53 | 只看该作者
一分钟读一次,就不抖了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表