使用STM32 ADC、电压分压器和噪声滤波器,对RT-Spark板上的CR1220纽扣电池和USB电压进行监测
1. 引言
本实验活动重点在于利用微控制器的模数转换器(ADC)外设来监测外部电压源。具体而言,该系统设计用于测量CR1220纽扣电池和5V USB总线供电电源的电压。对这些电平进行监测对于依赖电池作为备用电源的嵌入式系统非常有用,因为它能够追踪电源随时间变化的典型放电曲线,并在需要时安全地切换电源状态。
2. 设计与测试
该项目需要采用综合工程方法,结合模拟电路设计和嵌入式软件配置,以安全地读取环境数据,同时避免损坏硬件组件。
2.1 硬件架构与限制
虽然在特定条件下,低电压纽扣电池理论上可以直接连接到ADC输入引脚,但在测量5V USB总线电源等高电压源时,这种连接是不可行的。两个关键的硬件限制阻止了直接连接:
•物理电压损坏:将高于 VDD + 0.3V(在 3.3V 系统中约为 3.6V)的外部电压直接连接到微控制器引脚,将永久性地损坏其内部精密的 ADC 架构。
•传感器饱和:当输入电压超过系统规定的高模拟参考电压标准(3.3V)时,ADC 将返回一个所有二进制位均为 1 的饱和数字读数(十进制值为 4095)。
为克服这些限制,我们在面包板上设计了一个精密的电阻分压器。通过选择匹配的电阻值 R1 = 1MΩ 和 R2 = 1MΩ,输入电压被精确地缩小至原来的 0.5 倍。在该硬件配置下,3.0V 的输入信号被降至安全的 1.5V,而 5.0V 总线输入则被截断至 2.5V,确保两个信号均安全低于 3.3V 的模拟上限。
特意选择了极高的电阻值(1MΩ),以确保分压电路中通过的总电流保持极小(约1.5μA)。这有效限制了在监测过程中电池不必要的放电。通过在后续版本中调整该电阻比值,系统可适应不同电池化学类型的电压读取。
2.1.1 物理连接
物理电路在标准面包板上构建,并直接连接到微控制器的GPIO端口信号,具体如下:
•为了监测电池电压,将一个测试夹(或一根小跳线)连接到纽扣电池座的正极,并接入分压器(R1)的输入端。
•电阻分压器中间接点的缩放输出通过跳线直接传输到RT-Thread RT-Spark开发板上指定的模拟通道引脚(PA1)。
•电池座的负极被牢固地连接到开发板的接地(GND)引脚,以建立一个共享的参考平面。
2.2 软件配置与执行逻辑
为了与物理硬件进行交互,嵌入式软件参数通过STM32CubeMX初始化,并在STM32CubeIDE开发环境中进行编程。
•初始化配置:ADC1已启用,并映射到通道1(PA1引脚),采用12位分辨率模式。该设置将平滑的、真实的模拟信号转换为一个离散的数字阶梯,范围从0(对应0V)到4095(对应3.3V)。连续转换模式被禁用,以便软件循环可手动控制每次测量步骤。
•执行逻辑:建立了一个无限的 while(1) 处理循环来轮询传感器。代码使用抽象函数 HAL_ADC_Start() 启动 ADC 通道,通过硬件轮询函数等待转换过程完成,并使用 HAL_ADC_GetValue() 提取原始数字整数值。
•数学校准:为抵消面包板硬件引起的物理分压,软件数学方程中引入了2.0的标量乘数因子,以计算出真实的原始电压(vbat)。
•噪声滤波策略:为消除自然背景的电气噪声,编写了一个10采样软件平均滤波回路。固件会采集十个独立的原始快照,将其累加到一个累计和变量中,并计算出一个平滑且数学上稳定的均值(vbat_avg)。在每个子采样之间插入5毫秒的短暂延迟,以允许模拟信号线完全稳定。
3. 文档
以下是写在 main.c 文件中的核心操作源代码,用于处理变量、原始数据转换、缩放数学运算以及软件噪声滤波序列。
•vbat(瞬时电压):该变量捕获了ADC引脚(3.23311353V)上的一次快速瞬时信号。由于是原始数据,它会因面包板上的背景电气噪声而不断波动。
•vbat_avg(平均电压):该变量显示的是经过噪声滤波后的最终输出值(3.31238103V)。它通过连续快速采样十次后计算得出的稳定数学均值,因此更加可靠,且对突发波动具有更强的抗干扰能力。
•原始ADC(数字代码):这是转换器硬件直接生成的12位整数(2060),用于将物理电压缩放到0(对应0V)到4095(对应3.3V)之间的数字步长,该值作为所有代码电压计算方程的起始值。
4. 结果
监控框架已完整编写,运行在物理开发硬件上,并使用调试工具进行分析。
4.1 定量分析
在软件执行前,使用校准过的手持式数字万用表确定了测试环境的物理基准电压值:
•真实电池电压(Vbattery):3.28V
•PA1引脚的硬件电压分压:1.64V
•ADC高参考电源轨(V_RefH):3.3V
•电阻1(R1)的测量值:0.991MΩ
•电阻2(R2)的测量值:0.993MΩ
当固件执行时,IDE调试器内的实时变量检查器记录到计算出的原始软件电压值(vbat)为3.23V(具体读取值为3.23311353 V)。
将计算出的软件输出结果与实际物理万用表测量值3.28V直接对比,仅存在0.05V的微小差异。这相当于约1.5%的较小误差范围。这种微小偏差在嵌入式电路中完全正常,且从数学上来说,也得到了现实世界中电阻器所具有的微小制造公差的合理解释。
4.2 定性分析(平均滤波的影响)
为了评估10样本软件滤波器的性能,数据在多个运行周期中进行了收集,并对单个测量变量与平均测量变量之间的实时变化进行了汇总记录。
4.2 定性分析(平均滤波器的影响)
为了测试10样本软件滤波器的性能,我们对多个运行周期的数据进行了收集。系统以两种不同方式进行了测试,以观察背景电噪声对最终读数的影响。
未经滤波的测试(单次快照)
在第一阶段,电压未经过任何滤波直接记录。在五次独立的测试运行中,原始电压显示了以下数值:
•3.24 V、3.25 V、3.29 V、3.28 V 和 3.24 V
这些读数显示了微小但可见的跳变。这种变化是由于正常电气背景噪声通过物理电路而自然产生的。
滤波测试(10个样本平均)接下来,代码被更新以包含一个10个样本的平均循环。在使用这种新滤波器进行的五次测试运行中,平滑后的电压结果如下:
•3.239 V、3.312 V、3.241 V、3.304 V 和 3.307 V
通过取十个快速样本的平均值,而非仅依赖单一瞬时数据,电气噪声引起的随机电压尖峰得到了显著减少。这种滤波方法成功平滑了不可预测的输入信号,为系统提供了更加稳定和可靠的数据流。
5. 结论
实验成功演示了微控制器如何安全且具有高数学精度地与真实世界模拟环境交互。集成一种基于软件的基本滤波器,证明了其在清理来自嘈杂物理环境所采集数据方面是一种极具价值且低成本的资源。
5.1 技术反思
本次练习的一个重要工程启示是,系统依赖于一个固定的参考标准。经确定,如果开发板直接由与之要测量的电池完全相同的电池供电,该特定电路拓扑将彻底失效。
如果系统完全依赖被监测的电池供电,随着电池电量逐渐耗尽,ADC的基准参考电压(3.3V)会缓慢下降。由于代码中的数学公式被硬编码为假设3.3V基准电压始终保持不变,因此这种数学逻辑将失效。传感器的信号输出速率与正在衰减的电池以相同的速度缩小,导致ADC持续输出其最大数字值4095。这会使软件错误地显示电池已充满,直到系统突然断电并完全关闭为止。
5.2 遇到的问题及工程故障排查
在设置和测试阶段,遇到了三个明显的技术问题。
已解决:
未配置的项目模板和编译错误
问题:在项目创建和构建阶段,编译器因21个与缺失源文件头相关的致命错误而失败。这是由于IDE中的自动代码生成器包含了默认的中间件和模板配置结构,但这些结构未被正确配置或链接。由于这些额外功能与实际分配的固件完全独立,编译器无法找到它们的目录路径,导致整个构建过程中断。
解决方案:为了解决此问题,我们清理了项目结构,移除了活动构建路径中未配置的模板文件。项目仅限编译应用程序所需的核心必要文件:
•main.h, stm32f4xx_hal_conf.h, stm32f4xx_it.h
•main.c, stm32f4xx_hal_msp.c, stm32f4xx_it.c
•syscalls.c、sysmem.c 和 system_stm32f4xx.c
一旦将项目工作区隔离到仅包含这些特定的应用程序文件后,目录路径得以正确解析,固件成功编译,且无任何错误。
面包板上的电阻硬件不匹配
■问题:在早期硬件测试中,实时表达式窗口显示的原始数字值异常偏高,这给微控制器引脚带来了安全隐患。
解决方案:使用数字万用表对硬件电路进行了物理检查,发现R1插槽中意外插入了一个较小的131kΩ电阻,而非所需的1MΩ元件。将错误的部件更换为正确的1MΩ电阻后,PA1引脚的电压降至预期的基准值1.570V,从而保护了电路板。
调试器中数据日志跟踪的混淆
■问题:在为报告记录五次试验数据集时,系统变量的整理过程中出现了一次临时混淆。单个快照电压变量(vbat)最初被误认为是实时表达式配置界面中的软件平均变量(vbat_avg)。
解决方案:已完成对实时代码行为的审查,以分离数据。初始主循环运行中未经过滤的原始值已正确与平滑处理后的10个样本滤波均值分隔开来,确保报告数据在整个过程中完全准确。
本文编译自hackster.io





