![shequ.stmicroelectronics.cn](./template/st_v1/static/img/logo2.png)
前言 最近是有一个产品用到了ADC,使用的是STM32L051 芯片,使用 STM32CubeMX 生成的代码,本来以为简简单单,但是在调用 HAL ADC校准函数的时候遇到一个问题有点疑问,度娘一下也没有找到解答,还是经过翻阅了一些资料才得到答案,特此来记录一下。 一、ADC 配置说明详细的 STM32 ADC 的使用,本文不做过多说明,这个网上一搜一大把。 本文使用的是 HAL 库,直接用 STM32CubeMX 生成的代码,ADC 的配置步骤在我的另外一篇博文: STM32L051测试 (一、使用CubeMX生成工程文件 — ST系列芯片通用) 中有过介绍:
对于其他不同型号,F1,F4 等,配置大同小异。 2 y3 |; u% M% ^3 |2 U9 R" v 使用 CubeMX 可以大大简化工程师的使用步骤,这里直接说明一下对于使用 CubeMX 来说的 ADC 采样步骤。 ADC 采样使用步骤简单来说如下几步(以单次采样为例说明):
二、ADC 校准 在上面的步骤中,我把校准用了红色字体强调说明,因为在 ADC 的使用中必须进行校准 ,否者自己设计的电路得到的结果可能与实际的会有不同的偏差。 6 k) n! i5 ^& B3 C2.1 什么是ADC校准? STM32 的 ADC 校准一般有 参考电压校准 和 增益校准。 参考电压校准: 先测量 ADC 参考电压的实际值,然后将该值与预设的参考电压进行比较,得到参考电压的偏差,最终通过校准将其校正的方式叫做 参考电压校准 ,其目的是为了准确测量 ADC 的输入信号。 叫做增益校准: 通过测量内部基准电压和 ADC 输入信号的幅值之间的比例关系,校准 ADC 增益的方式 叫做增益校准,其目的是确保 ADC 输出的数值与输入信号的幅值之间具有良好的线性关系,为了准确的转换 ADC 输入信号。 ADC 校准的目的是为了消除 ADC 的偏移误差和增益误差,从而提高测量精度。 2.2 为什么 ADC 使用需要校准? 这个为什么要用 ADC 校准,我这里也只能简单的说明一下。 这个就像芯片生产过程制造中的差异化一样,ADC部分也存在一些差异化(虽然很小),其参考电压、偏置电压、增益等参数可能存在一些不确定性和漂移,这些参数的变化会导致 ADC 的测量结果产生误差。 就想上面介绍什么是 ADC 校准最后说的,为了提高测量精度,消除 ADC 的偏移误差和增益误差,所以在使用 ADC 采样的时候都需要进行 ADC 校准。 : X( z& w9 \! V6 |) r9 Q6 J2.2 什么时候使用 ADC 校准? 在我们使用 CubeMX 软件的时候,ADC 的配置,初始化等大部分程序都是由软件给我们生成的,我们都无需过多干预,但是校准是不会给我们自动加入程序的,这就需要我们 手动的添加。 在程序中,我们只需要保证在 ADC 开始使用前(ADC 转换函数调用前),ADC 初始化后,进行校准即可。 $ ^5 K- s1 A4 V ?; h2.3 ADC 采样每次都需要校准吗? 这个问题并不能直接回答,我们先来了解一下 调用了 HAL 校准函数以后,STM32 是怎么处理的。 调用 STM32 校准函数以后, 校准的结果会被保存在相应的寄存器中,以供后续的ADC测量使用。 由上面这句话可以知道,校准过后的结果会被保存起来,每次 ADC 使用的时候会从该寄存器中取校准数值,所以说一般来说,只要你上电校准过一次,就行了。 但是!注意,校准过后不用再校准是基于你的 ADC 设置没有改变,产品的工作环境稳定的前提下! 如果采样过程中你改变了 ADC 的环境,比如参考电压,采样时间等一些配置,或者一些低功耗产品,需要进行休眠,那么还是需要进行再次校准的。 还有一点,就是产品的工作环境,比如产品的环境比较恶劣,温度啊,干扰啊之类的,那么还是有必要在 ADC 的使用过程中进行定期校准的。 当然,如果我们本着严谨的作风,在产品上直接使用定期校准那也是没问题的。 三、HAL 库校准函数 上面理论的东西介绍完了,那么我们就来简单做个测试,其实我使用过程中的小疑问也是在使用过程中遇到的。 我们都知道 ADC 的校准函数为:HAL_ADCEx_Calibration_Start() 但是当我使用这个函数时候,居然出错了,如下图: ! T# |' ?/ Y; `2 _1 z! o) V
提示调用的参数太少了(确定出错是我编译过后发现的),提示函数调用参数太少了,这就奇怪了,于是我进入看看函数原型: 4 i% W. o& C) M# E! p
这里可以看到,怎么多了一个参数(上面确实有解释说明,应该填写什么),但是当时我第一反应是看一下这个参数在函数中是怎么用的,于是搜索了一下SingleDiff 这个参数,发现在HAL_ADCEx_Calibration_Start 这个函数中根本没用到这个参数? 为了搞清楚,我还去度娘问了下,发现根本没有关于这个参数的说明,所有的 STM32 ADC 有关的帖子文章,都是一样的, ADC 是啥啥啥,什么模式,解释一下,怎么用等等巴拉巴拉的…… - ^. m+ l+ v3 v+ Q3.1 单端校准和差分校准 其实上面的注释说明就是,这个参数就是用来选择使用哪种校准方式:单端校准ADC_SINGLE_ENDED 和 差分校准ADC_DIFFERENTIAL_ENDED。 5 J: X2 x6 H' H0 c后来就去翻阅手册资料,下面是查到的说明,这里给大家参考一下: 单端校准: 单端校准是指对 ADC 的单个输入通道进行校准,主要校准项包括偏移误差和增益误差。 单端校准主要针对单端输入的情况,通过比较参考电压和输入信号之间的误差,校准ADC的增益和偏置电压。在单端输入的情况下,参考电压和输入信号之间存在可能的偏差,这会导致ADC采样结果的偏移和误差。为了解决这个问题,可以使用单端校准来校正 ADC 的增益和偏置电压。单端校准的过程是使用一个已知的模拟信号来输入 ADC,然后比较采样结果与该模拟信号的期望值,得到增益和偏置电压的偏差值,然后通过校准将其校正。 单端校准时,ADC将使用内部参考电压作为参考电压,对每个输入通道进行测量,计算出偏移误差和增益误差,并将这些误差保存在相应的寄存器中。 差分校准: 差分校准是指对 ADC 的差分输入通道进行校准,主要校准项也包括偏移误差和增益误差。 差分校准主要针对差分输入的情况,通过比较参考电压和输入信号之间的误差,校准 ADC 的差分增益和偏置电压。在差分输入的情况下,差分增益和偏置电压的偏差也会导致 ADC 采样结果的偏移和误差。为了解决这个问题,可以使用差分校准来校正 ADC 的差分增益和偏置电压。差分校准的过程是使用一个已知的差分输入信号来输入 ADC,然后比较采样结果与该差分输入信号的期望值,得到差分增益和偏置电压的偏差值,然后通过校准将其校正。 差分校准时,ADC 将使用内部参考电压作为参考电压,并将两个输入通道的差值作为输入信号进行测量,计算出偏移误差和增益误差,并将这些误差保存在相应的寄存器中。 / h2 R, o/ r2 ^1 v) z3.2 不同系列的校准函数 所以在我们使用不同的系列的 HAL 库的时候,虽然校准函数都是HAL_ADCEx_Calibration_Start ,但是也有着一些参数的区别。 对于我目前使用的 STM32L051 来说,HAL校准函数使用的示例如下: HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);大部分情况下直接选择单端校准ADC_SINGLE_ENDED就行了,差分校准还需要外部电路的支持。 对于 STM32F 系列的来说,HAL校准函数使用的示例如下: HAL_ADCEx_Calibration_Start(&hadc1);5 G b( G' G) D( E...... 3.3 更多的校准模式 对于更多的系列,因为自己目前没有用到,我也没有一个一个去找,但是通过资料了解到,对于有些型号,比如 STM32F4 系列的,ADC的校准由硬件自动执行,不需要额外的调用 ADC 校准函数。 虽然我没有去试,但是这个硬件自动执行校准在 STM32CubeMX 中应该可以选择,因为他需要使能,在程序中的体现为: hadc1.Init.AutoCalibration = ENABLE;4 X6 w& c1 L- H; W+ E ?) ]5 M( G而且在 STM32 系列中,还有支持额外校准模式(共模校准、差分共模校准)的MCU,具体哪个我也不知道,这样的MCU,在使用校准函数HAL_ADCEx_Calibration_Start的时候又多一个参数。但是这里可以告诉大家在遇到的时候不要慌张,这里给出示例。 共模校准: /* 0 @: K2 r' n5 K$ B r2 v6 g6 Q! d使能共模校准 " [# f# Y( c, `5 Q, c- } */1 t/ E; V0 J5 ~5 U+ r9 a HAL_ADCEx_Calibration_Start(&hadc, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);# D R, b2 l5 d + @8 V' Z" k2 J /* 等待共模校准完成 */% U. t1 ]$ L5 u y% k while (HAL_ADCEx_Calibration_GetState(&hadc) != HAL_ADC_CALIBRATION_STATE_COMPLETED); 差分共模校准: /*( O# o7 Q# D) J8 i1 q使能差分共模校准 */' c1 I5 P, e7 j' Y: y HAL_ADCEx_Calibration_Start(&hadc, ADC_CALIB_OFFSET, ADC_DIFFERENTIAL_ENDED); : a' `; F7 I& n, |9 T3 I3 ^ /* 等待差分共模校准完成 ! w b0 c* j7 W */ while (HAL_ADCEx_Calibration_GetState(&hadc) != HAL_ADC_CALIBRATION_STATE_COMPLETED);5 l4 a/ h& k! Q. b3 W4 C" | 上面的 ADC_CALIB_OFFSET 是指定进行偏置校准。 4 S4 Z7 r" s* C! D: A$ K如有侵权请联系删除 转载自:矜辰所致9 c0 K. ]; m1 k8 l! W1 I |
分享一个STM32L031的串口调试程序
基于STM32L051使用CubeMX生成工程文件ST系列芯片通用经验分享
基于STM32L051开始添加需要的代码经验分享
STM32L051测试I2C协议设备的添加经验分享
基于STM32L051测试Flash和EEPROM的读写
基于STM32L051串口测试与Enocean模块通讯问题
基于STM32L0的EEPROM读写经验分享
【工程师笔记】汇总处
【经验之谈】基于STM32L053芯片使用STM32CUBE软件开发低功耗设备的经验分享
在 STM32L0 和 STM32L4 系列微控制器中使用 LPUART 使功耗最小