news 2026/9/9 19:50:56

基于STM32与HX711的电子秤设计:从传感器信号链到标定算法全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于STM32与HX711的电子秤设计:从传感器信号链到标定算法全解析

简介:这是一套基于STM32微控制器的完整电子秤设计项目,面向嵌入式初学者、电子竞赛选手及有课程设计需求的学生,覆盖称重系统从传感器采样、信号处理到显示输出的全链路开发。压缩包共225个文件,大小18.89MB,主要包含HX711驱动、LCD显示驱动、STM32工程源码(C/H文件)、原理图与PCB预览文件、物料清单以及详细项目报告PDF,所需代码和文档按模块分目录存放。已有3085人学习下载,是参考价值较高的实战资料。项目涉及GPIO配置、外部中断、定时器、ADC采集与均值滤波等核心知识点,结合原理图可理清传感器与主控的接口关系,报告则完整记录了设计过程、实施步骤与测试结果。按压缩包内目录依次推进,即可完成一个可运行的STM32电子秤原型,适合直接拿来作为课设或毕设的蓝本。 做电子秤这个项目,是我入门STM32时亲手完成的第一个带“传感器+算法+交互”的完整实战,也是很多毕业设计和课程设计的经典选题。别小看这台电子秤,它把信号采集、模拟放大、A/D转换、数值滤波、标定补偿这一整套嵌入式基本功全串起来了——做完它,你对STM32的理解会从“点灯”直接跳到“做产品”。

这篇我就从方案选型、硬件电路、HX711驱动、标定算法到实测调参、常见报错,完整拆一遍。适合正在做毕设、准备电赛,或想用STM32做一个能真正称重的设备的同学参考。网上这个题目的资料确实多,但大多是只贴代码不讲为什么。我这里尽量把每一步背后的原理和实际踩坑都讲透,照着做基本能一次跑通。

1. 方案选型与整体设计思路

1.1 为什么选STM32而不是51或Arduino

电子秤的核心需求其实不复杂:实时读取重量、稳定显示、支持按键校准。用51单片机也能做,但做出来的体验完全不一样。STM32的主频高、外设丰富,尤其是硬件I2C、定时器、DMA、多路ADC这些资源,给后期扩展留了很大余地。比如你想加蓝牙上传数据、加OLED菜单、接多个传感器,51的资源就会非常紧张,而STM32F103C8T6这种入门级芯片就能轻松扛住。

另一个关键点是开发效率。现在STM32CubeMX配置外设只要点几下鼠标,初始化代码自动生成,Keil里直接补业务逻辑就行。相比之下,51的寄存器操作虽然基础,但工程一大就容易乱。我做这个项目用的是STM32F103C8T6,也就是大家常说的“蓝板”,性价比高、资料多、坏了不心疼,特别适合新手第一块板子。

用Arduino也可以做电子秤,但我不推荐作为主方案。原因是Arduino的库帮你把底层全封装了,你调完库基本没搞懂信号是怎么来的。如果你是想学原理,STM32是更合适的平台;如果你只是想快速出个demo,那Arduino确实快,但这类毕设往往会被老师追问原理,答不上来就尴尬了。

1.2 系统框架:信号链与控制核心

电子秤的本质是把“力”变成“数字”。整个信号链是这样的:重力作用在称重传感器上,传感器内部的电阻应变片发生形变,导致电阻值变化,通过惠斯通电桥把电阻变化转换成微弱的差分电压信号。这个信号只有毫伏级别,没法直接送给STM32的ADC,所以中间必须加一级高精度ADC和放大器。

我用的是HX711模块,它内部集成了低噪声可编程增益放大器(PGA)和24位高精度ADC,专门为电子秤设计。HX711出来的数字信号通过两根线(DOUT和SCK)跟STM32通信,协议类似SPI但更简单,用GPIO模拟时序就行。STM32负责读取原始码值,做滤波、标定换算,最后把重量显示在LCD1602或OLED屏上,同时通过按键实现去皮、清零、校准。

系统里还有一个容易被忽略的部分:供电。HX711的模拟电源AVDD决定了ADC的参考电压,如果供电不稳,读数就会飘。所以我给HX711单独用了线性稳压供电,而不是直接从STM32的3.3V引脚上拉,实测稳定性会好很多。

1.3 传感器与ADC选型:HX711凭什么成为标配

称重传感器我选的是最常见的铝制悬臂梁式,量程5kg。这种传感器内部是四个电阻应变片组成全桥差分结构,量程范围覆盖厨房秤、邮资秤的常见需求。选量程有个原则:尽量让常用称重范围落在传感器量程的20%~80%之间,精度和线性度最好。如果你主要称100g以内的东西,却买了个50kg的传感器,分辨率会差到想哭。

HX711是这个项目的核心器件,它有两个差分输入通道,通道A增益可编程为64或128,通道B固定增益32。电子秤场景一般用通道A,增益128倍。它内部还有个特点:数据输出速率可选10Hz或80Hz。我实际测试下来,10Hz模式读数更稳,日常称重足够了。

有人会问,为什么不用STM32片内的ADC?因为片内ADC是12位分辨率,参考电压是3.3V,而传感器输出信号只有几个毫伏。就算你加一个外部运放放大100倍,12位的分辨率也很难做到0.1g级别。HX711是24位,即使考虑到噪声实际有效位数打个折,也能轻松分辨0.1g甚至更高,关键是它外围电路几乎不用设计,几个电容就搞定,太适合这种单点测量场景了。

2. 硬件电路的地基细节

2.1 惠斯通电桥与应变片原理

很多同学焊完板子读不出数,就开始怀疑程序,其实多半是没搞懂传感器内部的工作原理。应变片式传感器的核心是“电阻变化”:金属电阻丝被拉伸时变长变细,电阻变大;被压缩时变短变粗,电阻变小。但单个应变片的电阻变化率很小,只有千分之几,直接测电阻很难精准。

所以传感器内部把四个应变片接成惠斯通电桥。电桥的好处是:两个应变片受拉、两个受压,输出信号是两者的差值叠加,灵敏度翻了四倍,同时还能抵消温度引起的共模漂移。你可以把电桥想象成一把“电子天平”——它测的不是绝对电阻,而是两个桥臂的差值,所以非常灵敏。

惠斯通电桥的输出电压近似等于:Vout = Vex * (ΔR / R)。激励电压Vex一般是5V,ΔR/R在满量程时大概只有1mV/V级别。这意味着5kg满量程时,电桥输出大约5mV,真的很微弱。这种信号如果用普通运放,失调电压和温漂都比信号还大,必须用HX711内部那种斩波稳零放大器才靠谱。

2.2 HX711接线与STM32最小系统的关键点

HX711模块通常有八个引脚:E+、E-接传感器激励电源,A+、A-接传感器信号,VCC接电源,GND接地,DOUT和SCK接STM32的GPIO。接线本身不难,难在电源和地线处理。我的做法是:传感器E+和E-从5V取电,但要在靠近模块的位置加一个100uF电解电容和一个104陶瓷电容去耦,否则电机或继电器动作时读数会跳。

STM32最小系统部分有几个点我要特别强调。第一是Boot0引脚,正常运行时必须通过10K电阻下拉到GND,如果悬空或拉高,芯片可能会进入ISP模式,程序跑不起来。第二是复位电路,虽然STM32内部有上电复位,但外部还是建议加一个10K上拉电阻和0.1uF电容,防止干扰导致意外复位。第三是VDDA引脚,模拟电源必须单独接3.3V并加滤波电容,虽然这个项目ADC不用芯片内部的,但保持电源干净永远没坏处。

DOUT和SCK两个引脚我建议选择PA0和PA1,主要是方便后续接示波器或逻辑分析仪观察时序。两者之间不需要上拉电阻,因为HX711的DOUT是推挽输出,SCK是输入,电平匹配没有压力。

2.3 电源、显示与交互模块设计

整个系统的电源拓扑是这样的:USB的5V进来后分两路,一路直接给HX711的VCC供电,另一路经过AMS1117-3.3稳压后给STM32和OLED供电。这里有个细节,很多新手直接把5V接到HX711的VCC上,但HX711模块板上通常已经带了稳压电路,输入范围是2.6V到5.5V,所以5V没问题。不过要注意,E+和E-这两个给传感器的引脚,电压是跟随模块VCC的,5V供电时传感器激励就是5V,这个值是计算增益和量程的依据,别弄错了。

显示模块我试过LCD1602和OLED两种。LCD1602的优点是便宜、阳光下看得清,缺点是必须用I2C转接板才能省引脚,而且反应慢。0.96寸OLED用I2C接口,四根线搞定,显示数字字体大又漂亮,缺点是户外强光下看不清。如果是室内实验,我推荐OLED,颜值高,调试信息还能同时显示原始码值和换算后的重量,方便定位问题。

按键我接了三个:去皮键、校准键、开关机键。去皮键用中断触发,校准键用查询方式,这样能同时体验两种编程方式。蜂鸣器可以加一个,用三极管驱动,称重稳定后短响一声提示读数锁定,这个交互细节在实际使用中非常提升体验。

3. 软件驱动与核心算法实现

3.1 开发环境与工程初始化

软件部分我用的组合是STM32CubeMX + Keil MDK。CubeMX负责外设初始化,Keil写业务逻辑。工程里需要启用的外设不多:GPIO、一个定时器作为系统时基(我用TIM2做1ms中断,用于按键消抖和OLED刷新节拍)、I2C(如果用OLED的话)。

GPIO的配置有个容易踩的坑:HX711的DOUT是输入,SCK是输出,但SCK拉高的时间必须足够长。HX711的数据手册要求SCK高电平时间至少1微秒,如果GPIO速度配置成Low,再赶上主频不高时,时序容易不满足。我建议把SCK对应的引脚速度设为High,实测没问题。

OLED用的是软件模拟I2C还是硬件I2C?STM32F103的硬件I2C在早期固件库时代确实有点“玄学”,很多人被坑过。但用CubeMX生成的HAL库版本,只要注意加超时判断,硬件I2C基本是稳定的。如果你心里没底,软件模拟I2C反而更可控,反正OLED刷新频率不需要很高。我最终用的是软件模拟,省心。

3.2 HX711时序驱动:读原始码值

HX711的通信时序非常简洁,只有两根线。每次转换完成后,DOUT引脚会被拉低,这时STM32开始向SCK发送脉冲:发送24个脉冲读出24位数据,再发送第25个脉冲,DOUT就会恢复高电平,同时HX711开始下一次转换。

核心驱动代码如下:

uint32_t HX711_Read(void) { uint32_t value = 0; uint8_t i; // 等待数据就绪,DOUT拉低表示转换完成 while (HAL_GPIO_ReadPin(HX711_DOUT_GPIO_Port, HX711_DOUT_Pin) == GPIO_PIN_SET); // 读取24位数据,MSB first for (i = 0; i < 24; i++) { HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_SET); value = value << 1; HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_RESET); if (HAL_GPIO_ReadPin(HX711_DOUT_GPIO_Port, HX711_DOUT_Pin) == GPIO_PIN_SET) { value++; } } // 第25个脉冲,进入下一次转换 HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_RESET); return value; }

读出来的value是一个无符号32位整数,但HX711输出的是24位二进制补码。如果直接当无符号数用,负值会变成很大的正数,标定时就会乱套。正确的做法是把它转成有符号数:

int32_t raw = ((int32_t)(value << 8)) >> 8;

这个写法你可能第一次见,我解释一下:先把24位数左移8位放到有符号32位整数的最高位附近,再算术右移8位,利用C语言对有符号数的算术右移特性实现符号扩展,把原来的第23位正确变成符号位。这样空载时可能会出现小的正数或负数,都属于正常现象。

3.3 标定算法与数据平滑处理

标定是整个项目里最体现算法功底的部分。我的模型用的是最简单的线性映射:

实际重量 = (当前原始码值 - 零点码值) × 比例系数

比例系数的求法很简单:在空载时读取N次平均值作为zero_value,放上标准砝码(比如500g),读取稳定后的平均值作为span_value。那么每克对应的码值就是(span_value - zero_value) / 500,比例系数scale就是它的倒数。之后任意时刻的重量就可以通过上述公式算出来。

这里要特别强调平均值的作用。HX711虽然是24位ADC,但原始码值会有正负几到几十的随机跳动,这就是噪声。如果不滤波,你在显示屏上会看到数字一直在末尾跳动。我用的方法是去极值平均滤波:连续采样10次,去掉最大值和最小值,剩下的8次取平均。这样既能滤掉突发干扰,又不会像纯滑动平均那样滞后严重。

放砝码后读数不是一下子就稳定的,需要等一两秒让传感器和机械结构稳定下来。软件上可以加一个“稳定判定”:连续5次采样值的极差小于某个阈值(比如2个码值),就认为重量稳定,蜂鸣器响一声并锁定显示。这个小功能别嫌多余,实际用起来体验会好很多。

3.4 按键、显示与报警逻辑

UI逻辑我建议做成一个非常简单的状态机:正常称重状态、去皮状态、校准状态。按键短按去皮,长按三秒进入校准状态,此时屏幕提示放上标准砝码,再短按确认完成校准。状态机的好处是逻辑清楚,不会因为按键误触而乱套。

OLED刷新我控制在10Hz,太快了没必要,反而会因为I2C占用总线影响主循环。每次刷新显示两行:第一行是重量值,单位g或kg自动切换;第二行显示原始码值和当前状态,方便调试阶段观察。去皮的操作本质是记录一个tare_value,实际重量 = (raw_now - zero_value - tare_value) × scale,注意别把tare_value和zero_value搞混。

超量程报警也得写。当计算出的重量超出传感器量程的105%时,显示“Err”并蜂鸣器连续响。这个保护很重要,悬臂梁传感器超载时间长了会产生永久变形,标定就废了。

4. 调参、标定与实测精度

4.1 零点和满量程标定的具体操作

标定这件事,做得不严谨的话,后面精度全是空谈。我的操作流程是这样的:

  1. 上电预热5分钟,让电路和传感器温度稳定。
  2. 空载状态下连续读取30次原始码值,计算平均值,记为zero_value。这一步建议在软件里打日志出来,确认数值在一个稳定区间。
  3. 放置一个质量准确的标准砝码。砝码精度很重要,我用的是实验室的M1级砝码,如果手头没有,至少要保证来源可靠,别用一包没标称重量的零食。
  4. 等待读数稳定,读取30次原始码值,计算平均值,记为span_value,同时记录砝码质量mass_std。
  5. 计算比例系数scale = mass_std / (span_value - zero_value),单位是“克每码值”。

标定完成后,用不同重量的砝码回测,如果发现线性不好(比如小重量准、大重量偏差很大),大概率是传感器本身线性度差,或者机械安装有问题,而不是算法能解决的。

4.2 实测数据与误差分析

我标定完成后做了一组实测,数据大概长这样:

标准砝码实测显示偏差
0g(空载)0.0g0
50g49.9g-0.1g
100g100.1g+0.1g
200g200.0g0
500g500.2g+0.2g
1000g999.8g-0.2g

整体来看,满量程5kg的传感器配上HX711,在我的测试条件下能做到±0.2g以内的误差,重复性也不错。这个精度已经超过大多数家用厨房秤了。如果你需要更高的精度,可以从三方面改进:换用更高精度的传感器、增加机械限位和减震结构、软件上做多点标定修正非线性。

这里要提一个很多教程不会讲的事:HX711的增益误差和参考电压都会影响标定结果,但因为是比例测量,标定过程已经把这些误差“吸收”进scale系数了。所以只要你标定用的砝码足够准,系统的精度就不会差太多,这也是HX711方案在成本控制下依然能保证精度的原因。

4.3 提高精度的几个土办法

如果实测发现精度不够,先别急着换硬件,有几个成本几乎为零的办法可以试。第一是软件校准非线性,在标定时记录多个点的偏差,做一个查表插值修正。我实测5kg传感器在接近满量程时非线性会比较明显,做一个三点插值后误差能下降一半以上。第二是采样次数自适应,空载或重量稳定时增大平均次数,动态过程中减少平均次数,兼顾响应速度和稳定性。

还有一个经常被忽略的点:传感器的机械安装。悬臂梁传感器的固定端必须用螺丝牢固锁紧在底板上,受力端要保证受力方向垂直、不产生侧向力。很多“读数不准”的问题根源不在电路和程序,而在机械结构。你要是发现标定完放上去是准的,用手稍微按住就偏几百克,那肯定是机械上存在额外的应力路径。

5. 常见问题与排查技巧速查

5.1 常见故障现象与原因

做这个项目过程中,你会遇到各种奇奇怪怪的问题。我整理了一个排查表,基本覆盖了最常见的坑:

故障现象可能原因排查方法
读数恒为0xFFFFFF或不变DOUT接线错误、SCK时序不对、传感器信号线接反检查接线,用示波器看DOUT是否有跳变
读数慢慢漂移传感器预热不足、电源纹波大、机械结构松动延长预热时间,检查电源去耦电容
标定完用一会又不准传感器蠕变或温度漂移增加软件稳定判定,避免在传感器受力状态下长期静置
OLED不亮或花屏I2C地址不对、接线松动、电平不匹配扫描I2C地址,确认上拉电阻已接
重量显示负数传感器信号线接反、零点标定错误对调A+和A-,重新标定零点
ST-Link连接报错Boot0被拉高、SWD线序错误、供电不足检查Boot0跳线,确认SWDIO/SWCLK/GND/3V3四线连接

5.2 调试工具与排查顺序

排查这类问题,我建议按“电源→时钟→通信→算法”的顺序来,不要一上来就怀疑代码逻辑。上电后用万用表测HX711的VCC是否稳定在预期值,用示波器看传感器E+和E-之间是否有正常的激励电压,再看DOUT上电后是否会有高到低的跳变。DOUT如果一直不动,问题基本在传感器或模块端;只有DOUT正常跳变了,才值得去查STM32那边的GPIO配置代码。

调试时有个神器叫逻辑分析仪,二三十块的那种就行。把DOUT和SCK两根线夹上去,抓一段波形,数一下脉冲个数对不对、时序高低电平宽度够不够。很多时候你以为代码没跑对,其实芯片工作得好好的,是你时序看反了。

关于调试器连接报错,很多人会看到类似“Error: No STM32 target found! If your product embeds debug authentication...”的提示,这种情况十有八九是芯片没有进入调试模式,常见原因有:SWDIO和SWCLK两根线接反了、板子没供电、Boot0引脚悬空导致芯片进入ISP模式、或者芯片已经锁死。先查供电,再查Boot0,最后用ST-Link Utility做全片擦除,大部分问题都能解决。

5.3 避坑心得

最后分享几个我自己的实操心得。

第一,HX711模块买回来最好先检查上面有没有焊接跳线。有些模块通过跳线选择增益和通道,出厂默认是通道A、128倍增益,一般不用动,但如果你之前别人用过这块板子,跳线可能被改过,读数不对时可以检查一下。

第二,传感器的量程和精度要匹配。你买了个100kg的传感器,然后想称出0.1g的精度,那是天方夜谭。电子秤设计的第一步是先定量程和分辨率指标,再倒推传感器和ADC的选型,顺序反了后面会很痛苦。

第三,程序里一定要加看门狗。虽然是毕设,但做个完整的产品习惯很重要。I2C通信万一卡死在等待标志位,看门狗能自动复位,避免显示“卡死”的尴尬。HAL库里的I2C等待函数一定要加超时参数,别用while(1)死等。

还有一个让我印象很深的事:第一次做好样机时,显示数字总是每隔几秒莫名跳几十克。排查了很久,最后发现是USB供电线上的压降导致的。线缆太细、接触电阻大,HX711的模拟电源就会周期性抖动。后来我换了一根粗的USB线,问题立刻消失。电源问题往往是最隐蔽的,出问题先怀疑供电永远不会错。

这个电子秤项目做完,你手里就有了一套可复用的“传感器+24位ADC+MCU”模板。后续想扩展成智能台秤、人体秤,或者加蓝牙上传到手机App,硬件上只需改动传感器量程和通信模块,软件架构基本不动。做项目最大的乐趣也在于此:一个小东西做透了,很多底层问题就再也不会难住你了。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 19:47:41

HC32F460嵌入式开发:模板工程、启动文件与Keil配置实战

简介&#xff1a;基于HC32F460微控制器和LVGL图形库的工程模板&#xff0c;面向嵌入式开发者、电子竞赛参赛者及物联网产品设计人员&#xff0c;解决在SPI接口TFT-LCD上快速搭建图形用户界面的需求。该模板已完成HC32F460硬件SPI外设的时钟、引脚和传输配置&#xff0c;适配常见…

作者头像 李华