搜索
bottom↓
回复: 20

求助:STM32-ADC采样不准,计算误差0.16V

[复制链接]

出590入1001汤圆

发表于 2021-8-3 23:07:18 | 显示全部楼层 |阅读模式
本帖最后由 SUPER_CRJ 于 2021-8-4 12:06 编辑

修改日期:2021年8月4日12:1:31,终于找到原因了,感谢大家回复,楼主位更新:具体原因(放在楼主位最后。)感谢大家回复。

RT,检查了一下午加晚上没检查出结果,也换了两块板子,结果都是一样的,应该不是硬件问题。
之前一直没有做过模拟电路这块,本来准备通过计算ADC,计算干电池还有多少电。

具体:原理如图,大致是:把9V干电池:引出两个电阻串联分压后接到了:PB1引脚上,STM32F103RET6,通过多次的单次转换用平均值计算出电压。
结果:万用表电压:0.81V,ADC计算电压:0.65V这样。就是差电压。中间尝试加上0.1uf电容,增加转换时间,换分压电阻,始终不行,但是:如果强制引脚接GND或者3.3V其采样值是最小和最大。麻烦大神帮看看是什么问题。
具体代码(用的寄存器模式,都是按位操作的):
1:初始化
  1. { // ADC电池电压指示,根据手册:AMS1117-5.0最小可以到1.4V压差。
  2.                 // 所以在:5.0+1.4(6.4V) - 5.0+2V(7V)之间提示:更换电池!
  3.                 // 方案:采样16次,取平均值。
  4.                 { // GPIO配置:引脚配置为模拟输入模式
  5.                         RCC->APB2ENR.IOPBClockEnable_RW = ENABLE;
  6.                         GPIOB->CRL.InOutMode1_RW = GPIO_CR_INOUNTMODE_INPUT;
  7.                         GPIOB->CRL.PinConfig1_RW = GPIO_CR_PINCONFG_IN_ANALOG;
  8.                 }
  9.                 RCC->APB2ENR.ADC1ClockEnable_RW = ENABLE;
  10.                 RCC->CFGR.ADCPrescale_RW = 2;  // ADC6分频 - 禁止超过14MHZ
  11.                 RCC->APB2RSTR.ADC1Reset_RW = ENABLE;
  12.                 RCC->APB2RSTR.ADC1Reset_RW = DISABLE;
  13.                 { //
  14.                         ADC1->SQR1.RegularChannelSequenceLengthMinusOne_RW = 0;  // 拥有一个转换
  15.                         ADC1->SMPR2.SampleTime9_RW = 2; // 采样周期设置。
  16.                         ADC1->CR2.ADONEnable_RW = ENABLE; // 开启ADC转换
  17.                         for( vu32 i = 0;i<0xFFFFF;i++ );  // 校准前,要保持一定时间
  18.                         ADC1->CR2.ADCCalibration_RW = ENABLE;
  19.                         while(ADC1->CR2.ADCCalibration_RW == 1); //等待转换结束
  20.                         ADCalibrationValue = ADC1->DR.RegularData_R&0xFFF; // 获取校正值
  21.                 }
  22.                 for( vu32 i = 0;i<0xFFFFF;i++ );  // 等待20ms用来启动传输
  23.                 ADC1->SQR3.RegularSequence1_RW = 9; // 第9个通道。
  24.                 ADC1->CR2.ADONEnable_RW = ENABLE;  // 开启一次转换
  25.         }
复制代码


2:循环采集,同时计算:
  1. if( refreshDisCount == 0 ){ // 200ms左右的显示
  2.         { // ADC采样 - 使用单次采样,总共采样16次,使用平均值。
  3.                 // 采样16C时间:200*16 = 3200,大约3.2S
  4.                 ADC1->CR2.ADONEnable_RW = ENABLE;  // 开启一次转换
  5.                 while(ADC1->SR.EndOfConversion_RCW0 == 0); // 等待转换完成
  6.                 ADCValue_MV[adcCount++] = ADC1->DR.RegularData_R;
  7.                 if( adcCount >= 16 ){
  8.                         adcCount = 0;
  9.                         adcAvrValue = 0;
  10.                         for( u8 i = 0;i<16;i++ ){
  11.                                 adcAvrValue += ADCValue_MV[i];
  12.                         }
  13.                         adcAvrValue = adcAvrValue/16;
  14.                         adcAvrValue = ((adcAvrValue+ADCalibrationValue)*3300)/0xFFF; // 这是实际转换出来值,总是小0.16V左右,误差太大了。
  15.         }
  16. }
复制代码


具体原理图与PCB如下:




最终查找原因与结果:
单片机使用的AMS1117-3.3V由于大意,使用了AMS1117-5.0V,导致给单片机的电压实测为3.9V电压。而实际计算值用了3.3V计算,导致了错误。实测用了3.9V计算,结果正确。
关于回复中的一些问题:1:为什么直接拿电源接上引脚测量值会正确。因为此时9V电池被我摘下了,使用了调试器的3.3V供电,所以准确。2:使用100K和10K电阻可以用吗?最终测试结果:把电阻调整回来后,是可以的。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出200入2554汤圆

发表于 2021-8-3 23:42:00 | 显示全部楼层
没啥说的,一般都是 ADC 采样寄存器没配置正确

出675入8汤圆

发表于 2021-8-4 00:00:21 来自手机 | 显示全部楼层
额,adc有输入内阻的,你换成10k与1k的分压试试

出200入2554汤圆

发表于 2021-8-4 00:21:43 | 显示全部楼层
用 Arduino 编了一段,能确保寄存器配置没毛病,读取 PB1 电压并输出。

运行环境:F103 系列,8M 晶振,串口(PA9/10)可用,VCC=3.3V

运行方法:烧录 bin 文件,串口 9600 bps 接收测试结果。

附 Arduino 源码和 bin 固件:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入8汤圆

发表于 2021-8-4 08:59:56 来自手机 | 显示全部楼层
先读出17通道数据计算出verf 电压看看准不准。

出0入8汤圆

发表于 2021-8-4 09:11:08 | 显示全部楼层
万用表有没有问题?

出0入18汤圆

发表于 2021-8-4 09:59:16 | 显示全部楼层
你用电压跟随再进ADC试试

出0入8汤圆

发表于 2021-8-4 10:03:08 | 显示全部楼层
信号源输出阻抗太大。1.修改ADC配置,将采样时间加大试试。2.增加电压跟随器。

出0入8汤圆

发表于 2021-8-4 10:27:49 | 显示全部楼层

测试发现这个电阻对精度有影响。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出590入1001汤圆

 楼主| 发表于 2021-8-4 10:32:35 | 显示全部楼层
himan 发表于 2021-8-4 09:59
你用电压跟随再进ADC试试

问个问题:
如果把分压电阻减小到一定程度,是不是可以不用电压跟随器?

出590入1001汤圆

 楼主| 发表于 2021-8-4 10:34:05 | 显示全部楼层
xml2028 发表于 2021-8-4 00:00
额,adc有输入内阻的,你换成10k与1k的分压试试

昨天试了:换成10K和2K2的没有用。

出0入18汤圆

发表于 2021-8-4 10:40:46 | 显示全部楼层
SUPER_CRJ 发表于 2021-8-4 10:32
问个问题:
如果把分压电阻减小到一定程度,是不是可以不用电压跟随器? ...

想准确的话  就需要  因为mcu的内部ADC输入阻抗不是很大

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出590入1001汤圆

 楼主| 发表于 2021-8-4 10:49:18 | 显示全部楼层
skype 发表于 2021-8-4 10:27
测试发现这个电阻对精度有影响。

实测:加了这个电阻没有用。

出0入8汤圆

发表于 2021-8-4 11:03:02 | 显示全部楼层
用上图那个电路测试了下STM32F103CX的ADC,V_ADC处的电压软件读出来是0.6230925V,万用表测是0.625V. STM32的ADC很神奇,精度与PCB layout也有关系。

出590入1001汤圆

 楼主| 发表于 2021-8-4 11:21:33 | 显示全部楼层
t3486784401 发表于 2021-8-4 00:21
用 Arduino 编了一段,能确保寄存器配置没毛病,读取 PB1 电压并输出。

运行环境:F103 系列,8M 晶振,串 ...

谢谢。今天上午又测试了些,判断,应该和代码关系不大。
把电压源:直接接到采样电阻那里,误差就很小。实测几个电压值,只有0.01V左右的误差。
另外:请教下,我把采样电阻降低到1.5K和220R,实测还是有0.2V左右的电压差,难道一定要加电压跟随器吗?

出590入1001汤圆

 楼主| 发表于 2021-8-4 11:24:31 | 显示全部楼层
himan 发表于 2021-8-4 10:40
想准确的话  就需要  因为mcu的内部ADC输入阻抗不是很大

谢谢。
刚刚直接用电压源接到采样电阻处:就变的比较准了,误差只有0.01V。
但是回到板子上,实测:把采样时间调整到了最大,采样电阻换成了:1.5K和220R,按照如图应该是满足要求了,但是实测还有0.2V左右的误差。请教,这是什么问题。

出590入1001汤圆

 楼主| 发表于 2021-8-4 11:26:54 | 显示全部楼层
skype 发表于 2021-8-4 11:03
用上图那个电路测试了下STM32F103CX的ADC,V_ADC处的电压软件读出来是0.6230925V,万用表测是0.625V. STM32 ...

把电压源:直接接到采样电阻那里,误差就很小。实测几个电压值,只有0.01V左右的误差。
但是回到板子上,就又误差0.2V左右了。
我这边惟一的差别就是那个:0.1uf的电容了,会不会是那个影响了。

出0入16汤圆

发表于 2021-8-4 11:30:15 | 显示全部楼层
看看ADC的地和电源地差多少,地线也会有压降,而且3.3V也没有那么准的也会有压降,ADC的采样周期设成最慢的

出0入8汤圆

发表于 2021-8-4 11:34:15 | 显示全部楼层
SUPER_CRJ 发表于 2021-8-4 11:26
把电压源:直接接到采样电阻那里,误差就很小。实测几个电压值,只有0.01V左右的误差。
但是回到板子上, ...


我认为你PCB layout的时候,少放了这4个VDD的滤波电容的可能性更大。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出590入1001汤圆

 楼主| 发表于 2021-8-4 12:07:54 | 显示全部楼层
skype 发表于 2021-8-4 11:34
我认为你PCB layout的时候,少放了这4个VDD的滤波电容的可能性更大。

感谢解答,终于找到原因了,已放到了楼主位。答案不是这几个滤波电容

出590入1001汤圆

 楼主| 发表于 2021-8-4 12:08:54 | 显示全部楼层
初音之恋 发表于 2021-8-4 11:30
看看ADC的地和电源地差多少,地线也会有压降,而且3.3V也没有那么准的也会有压降,ADC的采样周期设成最慢的 ...

感谢回复,你的回答让我直接找到了原因,测量了下:AMS1117,发现用错了型号了,导致电压不对,感谢。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-16 14:28

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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