ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

STM32驱动HX711压力传感器称重实战:从接线到标定

STM32驱动HX711压力传感器称重实战:从接线到标定 简介一款以STM32为主控、结合HX711高精度24位A/D芯片的压力传感器电子秤项目资源说明文档中亦含STC90C52RC方案描述面向单片机初学者、电子设计竞赛选手以及需要快速落地称重功能的开发者。该系统在05kg量程内误差不超过±0.005kg除基础称重外还扩展了DS1302实时时钟、SC1010B语音播报、超量程报警并配合4×4矩阵键盘与1602液晶交互功能覆盖完整。压缩包共182个文件、5.08MB文件类型以C/H源码为主包含Keil工程文件uvproj、可直接烧录的HEX、编译中间文件OBJ/LST以及SCH原理图、PDF与Word说明文档从驱动程序、硬件连接到设计文档均有收录目录中还保留多种Bak备份便于对照修改过程。目前已有3605人学习浏览无论用于课程设计、毕业设计还是作为HX711压力传感器驱动与电子秤方案的项目基石都有不错的参考价值。 做电子秤、智能快递柜称重、机械臂末端力反馈甚至宠物自动喂食器里的余量监测这类项目十有八九会遇到同一个硬件组合STM32HX711压力传感器。我自己陆续用这个组合做过小量程称重模块、料斗余量检测和几套教学演示装置对这个方案的脾气还算摸得比较透。今天就把这套“STM32驱动5kg量程HX711压力传感器”的完整思路拆开说清楚从选型、接线、代码、标定到调试踩坑一篇讲完。适合刚入门想认真做完一个称重项目的朋友也适合被HX711读数跳来跳去搞到头大的同学参考。1. 项目定位5kg量程HX711为什么是这个组合1.1 5kg量程到底能干什么5kg是典型的“中等偏小”量程。相比几克到几百克的微型称重传感器5kg能覆盖更多日常场景小型电子秤、烘焙称、快递包裹称重、机械臂夹持力检测、3D打印机断料检测、智能垃圾桶满载提示这些都落在0到5kg区间。这个量程对应的传感器通常是电阻应变式悬臂梁或平行梁结构采用惠斯通电桥原理。受力时弹性体形变贴在弹性体上的应变片电阻发生变化电桥输出一个与受力近似成正比的差分电压。电压变化非常微小满量程5kg时典型输出灵敏度在1mV/V到2mV/V之间。也就是说如果给传感器激励电压5V满量程输出电压只有5mV到10mV。这么小的信号单片机内置ADC根本没法直接分辨必须经过高精度仪表放大器加ADC芯片放大、数字化这就是HX711存在的意义。1.2 为什么选HX711而不是STM32内置ADC很多初学者会问STM32的ADC不是有12位吗采集0到3.3V分辨出1mV也不是问题为什么还要外挂HX711问题出在“信号太小”和“参考电压不稳”两层。0到3.3V范围内测1mV12位ADC理论上确实能做到但那是在信号幅度接近满量程、参考电压非常干净的前提下。而称重传感器的信号只有5mV相当于ADC量程的千分之1.5LBSB级别的噪声和环境干扰就能把信号彻底淹没。如果为了匹配量程把信号放大128倍还要外接仪表放大器成本和复杂度上去了放大器的零漂、温漂又成了新麻烦。HX711把这套模拟链路集成到了一颗芯片里内部集成低噪声可编程放大器增益可选32、64、128、24位Σ-Δ ADC、稳压供电电路输出就是可直接读走的串行数字信号。价格便宜、外围电路简单、驱动时序容易用GPIO模拟简直是单片机称重项目的“万金油”。1.3 芯片选型F103C8T6足够别被“必须用高级型号”误导驱动HX711对主控的要求极低核心就是两个GPIO引脚——一个做时钟SCK一个做数据DOUT。IO翻转速度只要在几百kHz以内任何STM32都毫无压力。我自己最常用STM32F103C8T6也就是大家常说的“蓝 pills”32KB RAM、64KB Flash跑称重逻辑加OLED显示、按键处理绰绰有余成本还低。刚才热搜词里有个“stm32 f429 全局变量可以放在外扩sram”那是做大数据缓冲才需要考虑的场景。做称重F103完全够用别为了“性能冗余”去选更贵的型号省下的钱买个好点的传感器更实在。2. 硬件接线与供电先把物理层搞定2.1 传感器四根线怎么接5kg压力传感器引出线通常是四根红色E、黑色E-、白色S或A、绿色S-或A-。不同厂家颜色定义可能不同买之前一定要看说明书我最开始就吃过一次亏把信号线和激励线接反读出来的数值永远是满量程。接线顺序传感器E、E-分别接HX711模块的E、E-引脚这是给电桥供电的激励端。传感器S、S-分别接HX711模块的A、A-引脚这是差分信号的输入端。如果模块同时支持B通道把A通道作为主要称重通道B通道可留作备用比如接一个参考传感器做温度补偿。有些模块的A、A-之间已经并联了滤波电容焊接时注意别把焊盘短接到旁边的电源脚。2.2 HX711模块到STM32的接线与电平匹配市面上最常见的红色HX711模块引脚定义一般是VCC、GND、SCK、DOUT。接到STM32就三根线SCK接任意GPIO、DOUT接任意GPIO、GND共地。电源这里要重点说。HX711模块推荐工作电压是2.6V到5.5VSTM32F103的IO是3.3V电平。很多人担心5V供电的模块会把3.3V单片机烧掉实际测试下来红色模块的DOUT是推挽输出高电平接近VCC也就是5V直接接STM32的3.3V引脚确实有超过数据手册绝对最大额定值的风险。稳妥做法是模块电源用5VDOUT串联一个1kΩ电阻再进STM32。或者给模块用一个独立的3.3V供电。3.3V下传感器激励电压也是3.3V输出信号幅度等比缩小HX711内部放大128倍后依然在ADC量程内实测也能用只是信噪比稍微差一点。如果你用的STM32引脚恰好是5V容忍引脚比如F103的很多PA、PB口标准JTAG引脚直接连接问题不大。但我还是建议养成串电阻的习惯成本可以忽略防呆效果很好。2.3 供电方案3.3V能用但推荐5V我又做了一次对比测试同一只5kg传感器分别用3.3V和5V给模块供电空载时ADC读数噪声差不多但加载500g砝码时5V供电的读数跳变范围明显更小稳定性更好。原因很简单称重传感器的输出信号大小和激励电压成正比激励电压越高信噪比越高。所以我的建议是如果系统里有稳定5V电源优先给HX711供5V只有USB供电的时候再退而求其次用3.3V。供电纹波要控制在100mV以内最好在模块VCC和GND之间并联一个100μF电解电容和一个0.1μF瓷片电容。称重采集对电源安静程度的要求比普通LED闪烁项目高一个等级。2.4 硬件避坑清单传感器和模块之间的连线尽量短最好用屏蔽线或双绞线避免和电机、继电器等大电流线缆走在一起。传感器安装面必须平整、紧固悬臂梁传感器的固定端要固定牢受力端要悬空不受额外扭力。别超过传感器量程的120%过载会导致弹性体永久变形标定系数直接报废。模块和单片机之间共地必须可靠否则数字信号逻辑电平乱跳症状就是“读数偶尔变成满量程”。3. 驱动代码与标定把原始读数变成克数3.1 时序协议拆解DOUT和SCK到底怎么配合HX711的串行协议非常容易理解。上电后芯片持续进行转换DOUT引脚平时保持高电平当一次转换完成DOUT拉低表示“数据准备好了”。这时候单片机在SCK引脚输出脉冲前24个脉冲从最高位到最低位依次移出24位数据MSB在前。第25个脉冲用于选择下一次转换的增益同时也是A通道并触发下一次转换。注意如果第25个脉冲之后再给第26个脉冲对应的就是B通道、增益32。初学者很容易搞混最常见的错误是给完24个脉冲就停了结果下一次DOUT永远不会拉低。数据类型要特别留意HX711输出的是24位有符号数最高位是符号位。读取时要按有符号数处理不能直接当无符号数用否则空载时读数可能是个巨大的正数加载后又变成负数。3.2 驱动代码实现我一般用GPIO模拟时序不依赖硬件SPI这样随便换MCU平台代码都能复用。核心代码如下#define HX711_SCK_PORT GPIOA #define HX711_SCK_PIN GPIO_PIN_0 #define HX711_DOUT_PORT GPIOA #define HX711_DOUT_PIN GPIO_PIN_1 static uint8_t HX711_IsReady(void) { return (HAL_GPIO_ReadPin(HX711_DOUT_PORT, HX711_DOUT_PIN) GPIO_PIN_RESET); } int32_t HX711_Read(void) { uint32_t buf 0; uint16_t timeout 10000; // 等待DOUT拉低表示转换完成 while (HX711_IsReady()) { if (--timeout 0) { return 0x80000000; // 返回一个明显异常值表示超时 } } // 读24位数据MSB在前 for (int i 0; i 24; i) { HAL_GPIO_WritePin(HX711_SCK_PORT, HX711_SCK_PIN, GPIO_PIN_SET); delay_us(1); buf buf 1; if (HAL_GPIO_ReadPin(HX711_DOUT_PORT, HX711_DOUT_PIN) GPIO_PIN_SET) { buf; } HAL_GPIO_WritePin(HX711_SCK_PORT, HX711_SCK_PIN, GPIO_PIN_RESET); delay_us(1); } // 第25个脉冲切换回A通道增益128 HAL_GPIO_WritePin(HX711_SCK_PORT, HX711_SCK_PIN, GPIO_PIN_SET); delay_us(1); HAL_GPIO_WritePin(HX711_SCK_PORT, HX711_SCK_PIN, GPIO_PIN_RESET); // 24位有符号数转int32 if (buf 0x800000) { buf | 0xFF000000; } return (int32_t)buf; }这段代码有几个细节需要注意等待DOUT拉低必须加超时否则HX711没焊好或者SCK脉冲数错了程序会死在这里。我见过有人卡在while循环里整块板子看起来就像“跑飞了”。SCK频率不要太高1μs高、1μs低大约500kHz完全满足要求。SCK太快会超过HX711最大时钟频率读回来的数据随机跳。延时函数用简单的循环即可不需要精确到微秒只要别太快就行。3.3 标定原理与实操两点法就够了拿到原始AD值之后关键一步是换算成重量。HX711读出来的数是相对值不是绝对值。比如空载时可能稳定在100000左右放上500g砝码变成200000那么这段“差值”除以重量就是每克的AD增量。两点标定法步骤如下空载稳定后连续读取100次取平均记为zero。取平均是为了滤掉瞬时噪声。放上已知重量的标准砝码建议接近量程的80%比如5kg传感器放2kg或3kg砝码这样算出来的斜率误差最小。等待读数稳定后连续读取100次取平均记为load_value砝码重量记为weight_g。计算比例系数scale (load_value - zero) / (float)weight_g;之后任意时刻的重量weight_g (current_value - zero) / scale;这个scale就是“每个AD计数代表多少克”。理论分辨率算起来很有意思5kg量程、24位ADC理想分辨率是 5000g / 2^23 ≈ 0.0006g但HX711实际有效位数通常只有19到21位加上机械振动和电源噪声实测稳定分辨率能做到0.5g到1g已经很理想。如果有人告诉你“HX711能测0.01g”那大概率是拿高精度小量程传感器配高倍平均才实现的5kg量程不要抱这种期望。实测一次标定中我用2kg标准砝码空载零点是104832加载后是789652那么 scale (789652 - 104832) / 2000 342.41。之后读取当前值减去零点再除以342.41就得到克数。3.4 滤波和去皮让读数稳定下来实际使用中原始AD值会有±2到±5个LSB的跳动对应到重量可能就是±0.5g到±1.5g。这个噪声对很多场景可以接受但如果要显示到0.1g必须做软件滤波。我用的是“滑动平均去极值”组合每次读取10个样本去掉最大最小各1个剩下8个取平均。这样既能滤掉脉冲干扰又不会因为取平均导致显示值“拖泥带水”。如果追求更高的响应速度可以把窗口缩小到5个样本如果追求稳定度窗口扩大到20个但响应会迟钝。去皮功能Tare是称重的标准操作放上空容器按一下去皮键程序把当前读数记录为新的零点。注意这里要更新的是zero不能把当前重量清零后忘了换零点否则后续读数是绝对的不是相对容器的。4. 常见问题与排查技巧实测最常翻车的几个点4.1 ST-LINK连接失败error: no stm32 target found搜索热词里出现“error: no stm32 target found”这是调试器连不上芯片的经典问题。出现这种情况时先别急着怀疑代码九成是物理链路问题确认ST-LINK的四根线SWDIO、SWCLK、GND、3.3V都和板子对应引脚连接正确SWDIO和SWCLK交换会直接报这个错。确认目标板已经上电且供电正常。有些小板子用ST-LINK供电时电流不足上电瞬间电压跌落芯片起不来。如果芯片之前被烧过禁用JTAG/SWD的代码也会连不上。解决办法是按住复位键点击“Connect”以最高速连接在连接瞬间松开复位或者使用ST-LINK Utility的“Connect under reset”模式。这个坑和HX711本身没关系但一旦连不上芯片后面什么都做不了所以单独提一下。4.2 HX711读数一直跳、乱变我把这个问题归类为三类原因供电问题模块电源纹波大或者USB供电同时带动电机、舵机等大电流负载。检查方式是看读数的跳动是否有规律是不是和大负载启停同步。解决方法是给HX711独立供电或加稳压、滤波。时序问题SCK脉冲太快、延时太短读回来的数据在边界上乱跳。把高低电平延时加到2μs试试。地线问题STM32和HX711之间地线没连或者地线过长、过细数字地模拟地混在一起。单独用一根粗线把两者地连起来能解决很多奇怪的干扰。4.3 标定之后读数还是不准两点标定法假设传感器是纯线性的但实际传感器有非线性误差、滞后hysteresis和蠕变creep。标定时砝码质量不准、加载方向不对、传感器安装面不平都会导致系数偏差。经验做法标定时多采几个点比如空载、500g、1kg、2kg、3kg、4kg做分段线性插值或者最小二乘拟合。工业自动秤甚至要做温度补偿。如果只是做个家用电子秤两点标定已经够用但要注意标定过程从空载到加载再从加载到空载观察两个过程的读数差这个差就是滞后误差。持续高载荷下读数会缓慢漂移这是蠕变属于传感器的固有特性无法完全消除。上电后预热10分钟再标定能有效减小温漂影响。4.4 排查速查表现象可能原因处理方法上电后DOUT一直高电平传感器线接错、SCK脉冲数不对、模块损坏检查线序确认每次读取给25个脉冲读数恒为满量程或0xFFFFFF信号线接反、电桥未工作交换S和S-读数正常但加砝码不变化传感器固定端和受力端装反、弹性体卡死重新安装确认受力可以自由形变读数呈周期性波动电源50Hz纹波干扰增加滤波电容软件加50Hz陷波或平均滤波标定系数每天都不一样温漂、传感器老化、零点未更新上电预热每次开机自动去皮定期重新标定5. 几个我自己养成的开发习惯供你参考5.1 先看原始值再谈精度很多人一上来就写OLED显示重量结果发现读数乱七八糟。我的习惯是硬件接好先只跑串口循环打印原始AD值。观察空载时数值是否稳定、用手按压传感器时数值是否灵敏变化。原始值正常了再去做换算和显示问题排查范围会小很多。5.2 标定参数存进Flash标定出来的zero和scale是宝贵的成果不能每次重启都让用户重新标定。我会在系统初始化时尝试从STM32内部Flash读取存储的标定参数如果Flash里没有有效标志才进入待标定状态。这样每次上电就能直接显示克数体验好很多。F103的Flash操作不复杂注意写入前先擦除扇区且不要频繁擦写。存储结构可以定义成结构体加CRC校验能防止读到损坏数据。5.3 响应速度和稳定度要做取舍最后聊一个实操感受。滑动平均窗口越大读数越稳定但称重响应越慢放在自动分拣设备上会明显滞后。我通常的做法是窗口设成10个样本但显示更新频率保持在10Hz以上。对更严苛的场景可以先快速判断重量是否剧烈变化——变化大时缩短窗口变化小时拉长窗口动态调整滤波强度。这种自适应滤波写起来不复杂效果却立竿见影。这个组合看起来简单真正做精需要关注的细节并不少。希望这篇东西能帮你少走几步弯路。后面我还会再写一篇关于多传感器校准和温度补偿的实操笔记到时候接着聊。本文还有配套的精品资源点击获取
返回列表