免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

STM32智能电子秤实战:HX711传感器驱动与滤波校准全解析

STM32智能电子秤实战:HX711传感器驱动与滤波校准全解析 简介本资源是一套基于STM32微控制器的智能电子称完整毕业设计实践包面向嵌入式初学者、电子信息类本科生及毕设备赛学生解决从硬件搭建、程序开发到文档撰写与答辩展示的一站式学习需求。压缩包共723个文件含281个C源码与183个头文件实现AD采集、滤波算法、LCD/OLED显示、串口通信等核心功能36个编译中间文件.o/.d及18个PDF技术文档含原理图、PCB图、传感器模块资料、系统报告与答辩技巧另有Hex固件、Keil工程文件.uvproj/.uvprojx及流程图与软件分析说明整体大小为39.61MB。已有950人下载学习内容覆盖硬件选型依据、多级软件架构设计、称重信号数字滤波实现细节、低功耗优化策略并附有完整项目目录结构与模块化注释便于理解系统集成逻辑与快速复现实验。 开头我就说句实在话在 2024 年还愿意拿 STM32 做智能电子秤项目要么是课程设计、毕业设计赶鸭子上架要么是真想把这个经典外设组合吃透。无论哪种这个选题都不亏。STM32 加 HX711 加应变片压力传感器再加一块 OLED 屏几乎把嵌入式开发里最常用的 GPIO、定时器、中断、ADC、串口、IIC 外设全串起来了。市面上的电子秤方案不少有直接用专用称重芯片的有拿 Arduino 加模块拼的但用 STM32 自己写驱动、自己调滤波、自己管校准才是真正能把称重这件事从传感器原始数据到稳定显示全链路搞明白的路径。这篇博文我就以基于 STM32 的智能电子秤这个项目为蓝本从方案选型、硬件设计、驱动实现、校准标定到踩坑实录把关键环节完整拆开讲一遍。内容偏向实战适合刚学完 STM32 基础外设、想做一个完整项目的朋友也适合正在为课程设计发愁的同学直接参考。1. 项目整体设计与方案选型1.1 智能电子秤的系统架构先把整个系统的框架理清楚。一个典型的 STM32 智能电子秤核心链路是这样的传感器应变片电桥→ 信号放大与 AD 转换HX711→ 主控STM32→ 显示OLED与交互按键/串口称重传感器输出的本质是微弱的差分电压信号这种信号直接接到 STM32 的 ADC 上是没法用的原因是 STM32 内部 ADC 的分辨率和参考电压精度不足以分辨应变片在几十克重量变化时产生的毫伏级电压差。所以必须在前端加一颗专用的 24 位高精度 AD 芯片把模拟信号放大并数字化。HX711 就是干这个的。它内部集成了低噪声放大器增益可配置为 32 倍或 128 倍输出 24 位数字信号通过两根线PD_SCK 和 DOUT和主控通信。这个通信时序非常简单属于用 GPIO 模拟都能轻松搞定的级别也正因如此HX711 在称重项目里几乎成了事实标准。主控选择 STM32F103C8T6也就是大家常说的蓝丸核心板。这颗芯片虽然老但价格便宜、资料丰富、引脚够用对于电子秤这种对算力要求不高的场景来说完全够用。整机功耗也不高电池供电没问题。显示部分我推荐用 OLED。这里有个选型细节值得说一下OLED 有 IIC 接口和 SPI 接口两个版本。对于电子秤这种刷新率要求不高的场景IIC 接口更合适因为它只占两个引脚接线也简单。SPI 版本的刷新率确实快但你称重界面根本不需要一秒刷 30 帧IIC 完全能胜任还省下了两个引脚给其他功能用。1.2 为什么选 STM32 而不是 Arduino 或者专用芯片很多人会问电子秤这种项目用 Arduino 加 HX711 库几十行代码就搞定了为什么还要用 STM32 折腾这个问题的答案其实也是这个项目的核心价值所在。Arduino 方案确实开发快但对于学习嵌入式的人来说它把太多的底层细节封装掉了。你用 Arduino 的HX711库几行代码读出重量但你知道它内部是怎么用 GPIO 模拟时序的吗你知道为什么数据要多次读取取平均吗你知道校准系数是怎么算出来的吗这些问题的答案恰恰就是嵌入式开发的基本功。STM32 开发则逼着你把每一个环节都搞明白。HX711 的时序要自己用 GPIO 翻转去模拟数据滤波算法要自己写校准流程要自己设计甚至 OLED 显示都要自己初始化。这个过程虽然慢但做完之后你对主控如何与外部芯片通信如何从原始数据中提取有效信息这些问题的理解会达到一个完全不同的层次。再从实际角度说STM32 的资源优势是 Arduino 无法比的。比如你想在电子秤上增加蓝牙上传功能STM32 可以用串口直接接一个 HC-05 模块也可以自己写协议。想增加多个按键、多路称重STM32 的定时器、中断、DMA 资源都够用。后续想扩展 FreeRTOS 系统、加 LCD 触摸屏、做物联网远程监控都有足够的硬件基础。1.3 称重传感器量程选择与桥路原理传感器这块是整个项目最容易踩坑的地方因为很多人选传感器时只看价格不看量程和精度做出来的秤要么小重量测不准要么大重量直接超量程损坏传感器。常见的称重传感器有两种一种是单点式的就是那种铝合金方块四个角可以受力适合做小台秤另一种是悬臂梁式的一端固定一端受力适合做吊秤或改装成小秤。对于智能电子秤这种桌面级应用单点式平底传感器最常用。量程选择有一个经验法则你希望称量的最大重量应该落在传感器量程的 50%-70% 之间。比如你想最大称 5kg选 10kg 量程的传感器就比较合适。为什么因为传感器在量程的低端比如 1/10 处以下线性度和重复性都比较差精度很难保证。留出余量是因为称重瞬间可能会有冲击力长期满量程使用也会加速传感器蠕变。从原理上看电阻应变片式传感器内部是一个惠斯通电桥。受力时贴在弹性体上的应变片发生形变电阻值改变电桥失去平衡输出一个正比于负载的差分电压。这个电压一般来说非常小满量程时也就 1mV/V 到 2mV/V 左右。什么意思呢如果你给传感器供 5V 电满量程输出也就是 5mV 到 10mV。这么小的信号任何噪声、电源波动、温度漂移都会把它淹没这就是为什么必须用 HX711 这样的高精度前端来解决。2. 核心细节解析与操作要点2.1 HX711 通信时序与驱动代码编写HX711 的通信协议非常简单接口只有两个引脚DOUT数据输出和 PD_SCK时钟输入/掉电控制。基本时序是这样的当 DOUT 为高电平时表示数据还没准备好你等就行。当 DOUT 变为低电平说明转换完成数据可以读取了。此时你在 PD_SCK 上输出 25 个脉冲前 24 个脉冲在每个脉冲的上升沿从 DOUT 引脚读出一位数据高位在前。第 25 个脉冲用于选择下一次转换的增益和通道一个脉冲对应通道 A 的 128 倍增益两个脉冲对应通道 B 的 32 倍增益三个脉冲对应通道 A 的 64 倍增益。读取到的 24 位数据是二进制补码格式需要自己转换为有符号数。最简单的转换方法是如果最高位是 1就把整个 24 位数按位取反再加 1得到负数。我贴一段基于 HAL 库的驱动代码这里用 GPIO 模拟时序#define HX711_DOUT_PIN GPIO_PIN_6 #define HX711_SCK_PIN GPIO_PIN_7 #define HX711_GPIO_PORT GPIOC // 读取一次完整的 24 位数据 int32_t HX711_Read(void) { int32_t data 0; uint8_t i; // 等待数据就绪DOUT 拉低 while (HAL_GPIO_ReadPin(HX711_GPIO_PORT, HX711_DOUT_PIN) GPIO_PIN_SET); for (i 0; i 24; i) { HAL_GPIO_WritePin(HX711_GPIO_PORT, HX711_SCK_PIN, GPIO_PIN_SET); data data 1; if (HAL_GPIO_ReadPin(HX711_GPIO_PORT, HX711_DOUT_PIN) GPIO_PIN_SET) { data; } HAL_GPIO_WritePin(HX711_GPIO_PORT, HX711_SCK_PIN, GPIO_PIN_RESET); } // 第 25 个脉冲选择通道 A 128 倍增益 HAL_GPIO_WritePin(HX711_GPIO_PORT, HX711_SCK_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(HX711_GPIO_PORT, HX711_SCK_PIN, GPIO_PIN_RESET); // 24 位补码转有符号数 if (data 0x800000) { data | 0xFF000000; } return data; }这里有一个容易出错的地方DOUT 等待数据就绪的循环一旦 HX711 出问题比如接错线、供电异常这个 while 会死等导致程序卡死。所以在实际项目中我会加一个超时保护比如等待 100ms 后还没就绪就返回错误。这个习惯在写其他带通信协议的外设驱动时同样适用算是嵌入式开发的一个通用防呆思维。2.2 数据滤波与称重稳定性优化HX711 的原始数据波动比较大这是正常现象。主要原因有三个第一传感器本身有机械振动特别是你用手放东西的时候力不会瞬间稳定。第二HX711 内部虽然有低噪声放大器但电源纹波、周围电磁干扰都会耦合进去。第三24 位 ADC 的末几位本来就是抖动状态这是高精度 ADC 的正常表现。如果你把 HX711 的原始数据直接拿去显示会发现数字一直在跳。所以滤波处理是称重项目能不能稳定显示的关键。最简单的方案是滑动平均值滤波维护一个长度为 N 的缓冲区每次采样到新数据就入队同时把缓冲区所有数据的平均值作为当前输出。N 的取值需要权衡太大则响应慢放东西上去要等很久才稳定太小则滤波效果差。我的经验是 N 取 10 到 20 比较合适。以 HX711 的默认采样率 10Hz 算20 个点对应 2 秒的平滑窗口对于静态称重来说响应速度完全能接受。除了滑动平均还可以在中值滤波基础上叠加平均滤波也就是先去噪再平滑。具体做法是每次取 5 个原始数据去掉最大值和最小值剩下 3 个取平均。这样可以在考虑平均的同时剔除偶发的尖峰干扰。在工业称重里这种做法很常见。核心滤波代码可以这样写#define FILTER_N 20 uint32_t filter_buf[FILTER_N]; uint8_t filter_index 0; uint32_t filter_sum 0; // 每取得一个新原始值调用该函数 int32_t Filter_Process(int32_t new_value) { uint8_t i; uint32_t average; filter_sum - filter_buf[filter_index]; filter_buf[filter_index] new_value; filter_sum filter_buf[filter_index]; filter_index; if (filter_index FILTER_N) { filter_index 0; } average filter_sum / FILTER_N; return (int32_t)average; }这里有一个需要注意的细节我用的uint32_t来累加如果滤波窗口很长且原始数据很大累加和可能溢出所以filter_sum的大小要按项目的数据范围估算清楚。对于 24 位 ADC 的数据20 个点累加最大也就2^24 * 20 3.3亿左右uint32_t上限是 42 亿刚好够用。如果滤波窗口扩到 30 以上就得换uint64_t了。2.3 OLED 显示与按键交互设计OLED 显示屏我建议用 0.96 寸 128x64 分辨率的。驱动芯片是 SSD1306通信接口用 IIC。虽然手写 IIC 时序也不复杂但用 STM32 的硬件 IIC 外设会更可靠也释放了 CPU 资源。显示界面设计上有几个经验值得分享。电子秤的基本界面至少要包含这几部分当前重量主显示区大字号显示。单位g 或 kg跟随重量大小自动切换。去皮状态指示显示去皮或净重字样。电池电量OLED 显示区域有限用简单的电量图标即可。OLED 显示汉字是个麻烦事因为 SSD1306 需要取模数据。如果只显示固定内容可以把用到的汉字提前取好模放到一个数组里。基本每个汉字 16x16 点阵需要 32 字节存储空间。如果把界面控制得简单一些用 ASCII 字符和简单形状也能做出很清晰的效果。按键方面智能电子秤至少需要两个按键一个是去皮/清零一个是开关机或背光控制。按键电路要处理抖动问题硬件上可以用 RC 低通滤波软件上可以做消抖处理。最基础的软件消抖方法就是检测到按键电平变化后延时 10ms 到 20ms 再读一次确认电平没变才算有效按下。在这里要特别提醒如果使用 STM32 的内部上拉电阻接按键按键的另一端接地这种接线方式在按键松手后引脚会回到高电平。但如果你把按键接在 3.3V 上用下拉电阻逻辑就反过来了代码里要搞清楚。这看起来是小事但实际调试时方向搞反会让你以为按键坏了。3. 实操过程与核心功能实现3.1 开发环境搭建与项目初始化这个项目我用 Keil MDK 开发配合 STM32CubeMX 做初始化代码生成。很多人纠结用标准库还是 HAL 库我的看法是现在新项目直接上 HAL 库不要再纠结标准库了。原因很简单HAL 库是官方当前主推的方向CubeMX 生成代码支持到位而且网上教程多。标准库虽然启动更快、执行效率略高但已经停止更新新学的人没必要把时间花在过时的技术上。CubeMX 初始化配置要点如下时钟树STM32F103C8T6 最高 72MHz选择外部 8MHz 晶振PLL 倍频到 72MHz。IIC1开启用于 OLED。USART1开启波特率 115200用于调试输出。GPIOPC6 接 HX711 DOUTPC7 接 HX711 SCK均配置为普通输出PC6 需要配置为输入模式。一个定时器比如 TIM2配置为 1ms 中断用于超时判断和按键消抖。CubeMX 生成的代码骨架很完善你只需要在用户代码区添加自己的业务逻辑就行。这里有个经验不要在 CubeMX 生成的代码之外随便乱加函数尤其是中断回调函数一定要在指定的用户代码区里写。不然下次重新生成代码你写的部分会被覆盖掉找都找不回来。3.2 称重核心逻辑从原始值到实际重量这是整个项目最核心的部分也是很多人理不清的地方。HX711 读到的原始值是一个与施加在传感器上的力成线性关系的数字但它和实际重量之间没有一个固定比例。也就是说同一个传感器在不同的激励电压、不同增益下同样的重量对应的原始值是不同的。所以必须通过标定找到转换系数。称重的数学关系很简单重量 (当前读数 - 零点读数) × 校准系数这里有两个关键参数需要标定零点读数offset传感器上没有放任何东西时HX711 的稳定读数。理论上应该是 0但因为电桥不平衡、应力残留等原因实际值不等于 0。校准系数scale每克重量对应的 ADC 读数增量。比如放一个 100g 标准砝码读数比零点多了 82400那么校准系数就是 824。标定流程可以设计为开机后按住校准按键进入校准模式。此时 OLED 上显示请在秤盘上放置 100g 标准砝码。放好后按确认键系统读取当前读数减去零点读数再除以 100就得到了每克的 ADC 增量。把这个系数存到 STM32 内部 Flash 中下次开机直接读取不需要重复标定。这个流程看起来简单实际写代码时要注意一个细节进入校准模式后要等读数稳定再采样不然你取到的当前读数本身是跳动的算出来的系数就会有偏差。我一般会在确认后连续读取 20 个数据取平均再参与计算。还需要考虑超量程的情况。当重量超过设定最大值时OLED 上显示OVER并发出报警提示。这个判断要在换算成实际重量之后做因为超量程时传感器输出会非线性读数换算出的重量本身没有意义。3.3 去皮功能与重量单位切换去皮是电子秤的标配功能。所谓去皮就是把秤盘或容器的重量从读数中扣除只显示净重。实现思路是维护两个变量一个是传感器零点的初始读数另一个是去皮后的偏移量。具体逻辑是开机读取存储的校准系数读取当前读数作为初始零点。空秤下按去皮键把当前读数作为新的零点偏移。这时显示重量归零。放上物体当前读数减去零点偏移再乘以校准系数得到净重。放在代码里就是这样// 读取滤波后的原始 ADC 值 int32_t raw_value Filter_Process(HX711_Read()); // 减去零点含去皮偏移 int32_t delta raw_value - g_zero_offset; // 转换为克 float weight_g (float)delta / g_scale_factor;当容器拿掉后重量显示会变成负数。这属于正常现象很多商用秤也是这么处理的。但你可以加一个逻辑当检测到计算出的重量小于某个阈值比如 -5g自动认为容器已被拿掉归零一次。这个小细节能让使用体验提升不少。单位切换比较简单当重量小于 1000g 时显示g和克数大于等于 1000g 时显示kg和千克数。注意保留一位小数即可。3.4 参数存储与掉电保存校准系数和零点值必须掉电保存。STM32 没有 EEPROM但内部 Flash 可以用来存数据。F103C8T6 有 64KB Flash我们只用了很少一部分多余的地方完全可以用来存用户参数。Flash 写入要注意STM32 内部 Flash 编程前需要先擦除整个扇区而且写入必须按 16 位半字进行操作。如果你直接按字节写会触发硬件错误。另外 Flash 擦写次数有限制一般标称 1 万次所以不要在每次称重时都写 Flash只在参数更新时写。用 HAL 库操作 Flash 的基本流程// 解锁 Flash HAL_FLASH_Unlock(); // 擦除扇区F103 按页擦除每页 1KB FLASH_EraseInitTypeDef erase_cfg; erase_cfg.TypeErase FLASH_TYPEERASE_PAGES; erase_cfg.PageAddress PARAM_ADDR; erase_cfg.NbPages 1; uint32_t page_error 0; HAL_FLASHEx_Erase(erase_cfg, page_error); // 编程 16 位数据 HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PARAM_ADDR, (uint16_t)(param_value 0xFFFF)); HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PARAM_ADDR 2, (uint16_t)((param_value 16) 0xFFFF)); // 锁定 Flash HAL_FLASH_Lock();读取 Flash 就简单了直接指针操作即可。我还要提醒一点在写入参数时建议在数据尾部加上一个校验值比如把参数做异或或者简单的 CRC读取时校验一下不通过就使用默认参数。这样能避免 Flash 数据异常导致设备无法启动。4. 常见问题与排查技巧实录4.1 称重数据一直漂移停不下来这是电子秤项目里被问到最多的问题。实测下来我从这两点入手排查百分之九十都能解决。先看电源。HX711 对电源质量比较敏感如果直接用 STM32 核心板的 3.3V 给传感器和 HX711 供电而电源本身纹波大读数就会持续漂移。解决办法是给 HX711 的供电加一个 10uF 电解电容和一个 100nF 陶瓷电容做去耦电容尽量靠近 HX711 的电源引脚。有条件的话用独立的高精度稳压源给传感器供电模拟地和数字地单点连接。再看机械结构。传感器本身的机械稳定性至关重要。传感器要固定牢固不能有晃动空间。秤盘和传感器之间不能存在明显的重心偏移否则放上物体后力的作用点不在传感器承力中心读数就会在某个范围内来回跳。我之前调试时遇到过一种情况读数每隔几秒就缓慢上升最后查明原因是传感器的固定螺丝没拧紧导致弹性体在受力时发生了微小的滑移。4.2 校准系数每次算出来都不一样这种情况通常是因为校准时的参考重量不对或者标定过程中零点发生了变化。标准砝码的问题比较隐蔽。很多人图方便用一瓶矿泉水或者一袋米当标准重量但包装上标的重量可能偏差很大。矿泉水的净含量标签通常标的是 550ml实际质量可能只有 540g 左右。这种误差在标定阶段就被引入而且会被线性放大。我的建议是没有标准砝码就去买一个 100g 或 500g 的砝码不贵但能让你的校准结果有可信度。另一个原因是零点和标定重量不在同一条件下。比如开机后传感器还没有预热就直接标定此时零点和后续读数都处于漂移状态算出来的系数自然不稳定。正确做法是上电后先等待 30 秒到 1 分钟让传感器和 HX711 都稳定下来再进行零点采样和标定操作。4.3 HX711 一直读不到数据DOUT 始终为高这个现象基本可以确定硬件连接出了问题。优先检查以下几个方面供电电压HX711 的数字电源 VCC 和模拟电源 AVDD。AVDD 外部一般接一个 RC 滤波网络这个网络的电容建议选 100nF 到 1uF阻值选 10Ω 到 100Ω。如果 RC 参数不对HX711 上电后可能无法正常工作。时钟线是否真的在翻转用示波器或逻辑分析仪看 PD_SCK 引脚上有没有脉冲。没有示波器的话可以在代码里加一个延时让 SCK 翻转速度变慢再用万用表的频率档测一下。传感器接线和 HX711 输入端的匹配称重传感器的四根线红黑接激励 E 和 E-白绿或白黄接信号 A 和 A-。接线错误不会立即烧东西但读不到正确数据。如果以上都检查了还不行手动把 DOUT 引脚配成普通输出拉低看看能不能读到低电平。如果能说明 STM32 端配置没问题问题出在 HX711 本身或传感器上如果不能说明 STM32 引脚配置或硬件连接有误。这种分段排查的方法在嵌入式调试中非常有效。4.4 串口调试printf 重定向与调试技巧串口在这个项目里有大用处。跑滤波算法、看原始数据波动、验证校准效果都需要把数据打出来看。用 HAL 库时重定向 printf 到串口需要自己实现一个接口函数#include stdio.h int fputc(int ch, FILE *f) { HAL_UART_Transmit(huart1, (uint8_t *)ch, 1, 10); return ch; }加上这个函数后printf(raw %d\n, raw_value);就能往串口输了。要注意在 Keil 里勾选Use MicroLIB否则可能因为 C 库的底层需要处理fputc导致死机。调试时的常用技巧是用串口把这些数据周期性输出原始 ADC 值、滤波后值、计算出的克重、零点偏移。用一个简单的上位机串口工具比如 SSCOM就能实时观察。这种数据可视化的方法比盯着 OLED 上跳动的数字更直观也能更快看出滤波效果和异常波动。4.5 加一块蓝牙模块把数据传到手机做完基础功能后我这边的推荐扩展方向是加蓝牙。它的接入方式比较轻量不会大幅增加项目复杂度但价值感提升很明显。选 HC-05 或者 CC2541 这类串口透传模块接线非常简单模块的 TXD 接 STM32 的 RXRXD 接 TXVCC 接 3.3VGND 接 GND。要注意模块的电平是否兼容 3.3V很多蓝牙模块是 5V 供电但串口电平可以兼容 3.3V具体看模块手册。数据协议上我建议用 JSON 格式或者简单的自定义协议比如{weight:123.4,unit:g,stable:1}手机端用现成的蓝牙串口助手 App 就能接收和显示。如果要做成产品级可以自己开发一个简单的 App用 BLE 协议栈。不过这就是另一个话题了。5. 项目扩展思路与后续优化方向5.1 从单通道到多通道用 ADC 多通道扫描实现多路称重如果你觉得一个称重通道不过瘾STM32 的 ADC 多通道扫描模式可以派上用场。其实大多数电子秤产品只需要一个通道但如果你做一个双盘秤或者需要同时测量多个位置的力值分布就用到多通道了。用 STM32F103 内部 ADC 多通道配合 DMA 是一套经典组合。配置思路是在 CubeMX 中使能 ADC 的扫描模式选择多个通道比如通道 0 和通道 1序列长度设为 2开启 DMA 循环模式让 ADC 转换结果自动搬运到内存数组里。这样你只需要在主循环里读内存数组就能拿到各个通道的转换值。不过要提醒一点内部 ADC 做多通道扫描通道之间的串扰是客观存在的尤其是相邻通道。解决办法是在通道切换后忽略第一次转换结果也就是过采样丢弃法。这个方法虽然简单但在实际工程中非常实用。5.2 用 FreeRTOS 优化实时性与任务划分当项目变得复杂比如同时处理称重、OLED 显示、蓝牙通信、按键扫描、超量程报警裸机 main 函数里的 while 大循环就会变得拥挤而且各个功能之间的耦合越来越严重。这时候可以考虑引入 FreeRTOS。把功能拆成几个独立任务称重采集任务优先级最高周期性读取 HX711做滤波更新重量值。OLED 显示任务优先级低定时刷新显示。蓝牙通信任务中等优先级处理串口数据的收发。按键扫描任务通过队列或信号量通知其他任务处理按键事件。任务之间的数据交互重量值用一个全局结构体加互斥锁保护。这样做的优点是模块化程度高改一个功能不影响其他模块。缺点是工程复杂度上升而且要知道任务栈大小怎么分配不然会出现栈溢出。对于新手来说我建议先不着急上 FreeRTOS把裸机版本做稳定了再逐步移植到 FreeRTOS 上能更好理解操作系统的价值。5.3 低功耗优化从电池供电到更长的续航如果用电池给这个项目供电续航是必须考虑的问题。STM32 的低功耗模式是实现续航优化的关键。最简单的方法是当检测到秤盘上无物体重量接近零且无操作时进入 STOP 模式。此时主频停止所有时钟关闭只剩下少量外设如 RTC 可以工作。进入 STOP 模式前要把不用的外设全部 DeInit 掉特别是 HX711 和 OLED它们的静态电流不小。唤醒源可以用外部中断比如按键按下、重量变化引起的 IO 跳变。还有一个更细的优化点HX711 本身有掉电模式在 PD_SCK 引脚保持高电平超过 60us 后进入掉电状态。利用这个特性在 STM32 进入 STOP 前先让 HX711 掉电能把系统整体功耗降得更低。实测下来一个 2000mAh 的锂电池如果设计合理可以让电子秤待机数周。6. 一点个人经验总结做这个项目的过程中我踩过不少坑这里把这些经验分享给大家。对于 STM32 新手来说以下几个习惯建议尽早养成第一拿到一个模块先看它支持的通信协议不要上来就用现成的库函数。你现在能搜到 HX711 的各种驱动但哪天换了一个 HX720 或者别的芯片你不懂它的时序原理照样不会写驱动。通信时序的阅读能力是嵌入式工程师的基础功。第二数据格式和精度问题要在设计阶段就想清楚。HX711 的输出是 24 位有符号数中间计算用浮点还是定点显示要保留几位小数这些都影响代码的结构和运行效率。STM32F103 没有 FPU大量浮点运算会占用很多 CPU 时间。如果你发现程序响应变慢可以考虑用整型运算替代浮点比如把克重先乘以 10 存成整数显示时再除以 10。第三善用调试工具。示波器、逻辑分析仪、串口打印都是调试利器。尤其是分析 HX711 时序这类信号时逻辑分析仪能看到真实的波形比自己反复看代码猜问题高效得多。第四程序的健壮性设计要在线就做。比如 HX711 通信超时、按键防抖、Flash 写入校验这些不是可有可无的功能而是保证项目不崩的基础。很多新手做完项目只保证正常条件下能工作但真正好的工程应该是异常条件下不崩溃。这个智能电子秤项目麻雀虽小五脏俱全。从模拟信号采集、数字滤波、外设通信、按键交互、参数存储到低功耗设计几乎把 STM32 开发的核心点都覆盖了。做完之后你会发现再去学习其他传感器、其他通信协议、其他 MCU都有融会贯通的感觉。也正因如此这个项目无论是在大学课程设计还是个人技能提升都值得花时间好好做。本文还有配套的精品资源点击获取
返回列表