资讯动态

基于STM32的电子秤设计方案:从HX711信号链到标定滤波与验收全流程

发布时间:2026/10/17 11:24:59 来源:尧图企业网站定制
简介这是一套面向嵌入式初学者与电子设计爱好者的STM32电子秤完整项目资料围绕高精度称重场景解决从传感器信号采集到重量显示的全流程实现问题。资源包共225个文件约18.89MB以C源码与头文件为核心辅以工程配置、编译中间文件、原理图、PCB文档、物料表及项目报告等覆盖软件、硬件与文档多个层面。项目涉及STM32的GPIO、中断、定时器配置HX711称重传感器的驱动与通信ADC模数转换原理以及平均值滤波、滑动平均滤波等数据处理方法并包含LCD显示驱动与电源管理设计。已有3093人学习下载读者可据此复现完整电子秤方案理解信号采集、滤波计算与显示控制的实现思路同时参考原理图与物料表完成硬件搭建借助报告梳理设计步骤与调试经验适合作为课程设计、毕业设计或嵌入式入门的实践参考。1. 从“能称重”到“能交付”电子秤方案到底要解决什么做过电子秤的人都知道称重本身不难难的是把“称得准、显示稳、按键不飘、超载能报警”这几件事同时做进一块 STM32 里还要让评委或甲方一眼看懂你的设计逻辑。这套基于 STM32 单片机的电子秤设计核心不是堆功能而是用一套清晰的信号链把压力传感器、ADC 采样、数字滤波、标定算法和人机交互串起来。它适合正在做单片机课程设计、嵌入式毕设或者需要快速搭一台小量程电子秤原型的同学和工程师。称重范围、分度值、供电方式这些指标一旦定下来后面所有模块的选型和代码结构都得围着它转否则很容易出现“实验室能称、换个桌面就跳数”的玄学问题。2. 需求拆解与选型量程、精度、采样率怎么定2.1 从称重指标反推传感器和 ADC 配置电子秤的第一性指标是量程和分度值。假设做一台 5kg 量程、1g 分度的桌面秤满量程需要 5000 个可分辨刻度。电阻应变式称重传感器输出灵敏度通常是 1mV/V激励 5V 时满量程输出 5mV。要分辨 1g对应信号变化是 1μV。这个量级直接决定了你不能用 STM32 内部 12 位 ADC 随便采——内部 ADC 在 3.3V 参考下最小分辨约 0.8mV根本不够看。通常的做法是外挂 24 位 Σ-Δ 型 ADC比如 HX711 这类专为称重设计的芯片内部 PGA 可放大 128 倍等效分辨率能到 10nV 级别。STM32 在这里的角色是定时读取 HX711 的串行数据、做数字滤波、跑标定算法、驱动显示和按键。选型时注意HX711 的通道 A 增益 128 对应差分输入范围 ±20mV刚好覆盖传感器满量程输出通道 B 增益 32 用于其他检测。STM32 型号选 F103C8T6 就够72MHz 主频、硬件 SPI 和多个定时器价格和资料都友好。提示传感器量程留 20% 余量。5kg 量程的秤选 6kg 传感器避免长期满量程导致蠕变和零点漂移。2.2 采样率与滤波窗口的权衡HX711 输出速率可选 10Hz 或 80Hz。电子秤不需要高速采样10Hz 足够而且低速率下噪声更低。但 10Hz 意味着每 100ms 出一个原始值如果直接显示末位会跳得厉害。我一般会做两级处理第一级在 HX711 读取后做去极值平均连续采 10 个点去掉最大最小再取平均第二级做一阶低通滤波截止频率设在 1Hz 左右。// 一级滤波去极值平均window 长度 10 #define FILTER_WINDOW 10 int32_t raw_buf[FILTER_WINDOW]; int32_t filter_level1(void) { int32_t sum 0, min raw_buf[0], max raw_buf[0]; for (int i 0; i FILTER_WINDOW; i) { sum raw_buf[i]; if (raw_buf[i] min) min raw_buf[i]; if (raw_buf[i] max) max raw_buf[i]; } // 去掉一个最大值和一个最小值再算平均 return (sum - min - max) / (FILTER_WINDOW - 2); } // 二级滤波一阶低通alpha 越小越平滑但响应越慢 float filter_level2(float new_val) { static float last_val 0; const float alpha 0.2f; // 根据实际跳动情况调整 last_val alpha * new_val (1 - alpha) * last_val; return last_val; }这段代码里FILTER_WINDOW决定了一级滤波的平滑程度窗口越大越稳但响应越慢alpha是二级滤波的惯性系数0.2 意味着新值占 20% 权重。实际调试时先调alpha如果还跳再加大窗口。注意原始数据要先做零点扣除再进滤波否则滤波后的值没有物理意义。2.3 显示与交互的硬件选型显示用 0.96 寸 OLEDSSD1306 驱动I2C 接口比 LCD1602 更合适分辨率 128×64 能同时显示重量、单位、状态图标I2C 只占两个 IO 口。按键用三个轻触开关分别接“去皮/清零”“单位切换”“校准”配合 STM32 的外部中断或定时扫描。蜂鸣器用于超载报警和按键反馈有源蜂鸣器直接 GPIO 驱动即可。供电方面如果做便携式用 3.7V 锂电池加升压到 5V 给传感器和 HX711 供电STM32 用 3.3V LDO 从 5V 降压。注意 HX711 的模拟供电和数字供电要分开走线否则数字噪声会串进称重信号。3. 总体架构设计信号链、控制流与模块划分3.1 硬件信号链从应变片到 OLED 的完整路径整条信号链是称重传感器惠斯通电桥→ HX71124 位 ADC PGA→ STM32滤波 标定 逻辑→ OLED显示和按键输入。传感器四线制接 HX711 的 E、E-、A、A-HX711 的 DT 和 SCK 接 STM32 的任意两个 GPIO。STM32 通过软件模拟 HX711 的串行时序读取 24 位补码数据。这里有个容易翻车的点HX711 的 DT 引脚在数据未准备好时是高电平准备好后变低。如果 STM32 用外部中断去读中断里做 24 次 SCK 翻转容易被打断导致时序错乱。稳妥的做法是用定时器每 100ms 触发一次读取在定时器中断里完成整个读取过程或者用主循环轮询 DT 引脚。3.2 软件模块划分五个独立任务软件按功能拆成五个模块主循环里顺序执行采样模块定时读取 HX711存入原始缓冲区。滤波模块对原始数据做两级滤波输出稳定值。标定模块用两点法计算斜率scale和零点偏移offset重量 (滤波值 - offset) / scale。显示模块将重量值格式化为字符串刷新 OLED。按键模块扫描按键处理去皮、单位切换、进入校准模式。模块之间通过全局结构体传递数据避免层层传参。结构体定义如下typedef struct { int32_t raw; // HX711 原始值 float filtered; // 滤波后值 float weight; // 标定后重量单位 g float scale; // 斜率g per count int32_t offset; // 零点偏移 uint8_t stable; // 稳定标志 } Scale_t;scale和offset存在 STM32 的 Flash 模拟 EEPROM 里掉电不丢。每次上电先读这两个参数如果 Flash 里是空白的0xFFFFFFFF就进入默认校准流程。3.3 标定算法两点法为什么够用称重传感器的输出和重量在额定范围内基本是线性的所以两点法足够。具体操作空载时读一个原始值作为零点offset放上已知砝码比如 500g读一个原始值斜率scale (raw_with_weight - offset) / 500.0。之后每次称重weight (filtered - offset) / scale。注意标定用的砝码要选接近满量程的比如 5kg 量程用 4kg 或 5kg 砝码。用小砝码标定会放大斜率误差导致大重量时偏差大。如果要做多点标定可以在 20%、50%、80% 量程各放一个砝码用最小二乘法拟合直线。但对课程设计和一般毕设两点法完全够用代码简单且容易在答辩时讲清楚。4. 关键模块实现从 HX711 驱动到 OLED 刷新4.1 HX711 读取时序与代码实现HX711 的串行时序是DT 变低表示数据就绪然后 SCK 给 24 个脉冲每个脉冲上升沿读出一位第 25 个脉冲选择下一次的通道和增益。代码用 GPIO 模拟// HX711 读取一个 24 位值channel A gain 128 int32_t hx711_read(void) { int32_t value 0; // 等待 DT 变低超时退出防止死等 uint32_t timeout 0; while (HAL_GPIO_ReadPin(HX_DT_PORT, HX_DT_PIN) GPIO_PIN_SET) { if (timeout 100000) return 0; // 超时返回 0 } // 读 24 位 for (int i 0; i 24; i) { HAL_GPIO_WritePin(HX_SCK_PORT, HX_SCK_PIN, GPIO_PIN_SET); value 1; if (HAL_GPIO_ReadPin(HX_DT_PORT, HX_DT_PIN) GPIO_PIN_SET) value; HAL_GPIO_WritePin(HX_SCK_PORT, HX_SCK_PIN, GPIO_PIN_RESET); } // 第 25 个脉冲选择下一次通道 A 增益 128 HAL_GPIO_WritePin(HX_SCK_PORT, HX_SCK_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(HX_SCK_PORT, HX_SCK_PIN, GPIO_PIN_RESET); // 24 位补码转有符号 if (value 0x800000) value | 0xFF000000; return value; }timeout是防止 HX711 未接或损坏时程序卡死。第 25 个脉冲不能省否则下次读的是通道 B 增益 32 的数据。读出的 24 位是补码最高位为 1 表示负数需要符号扩展。实际调试时如果读出来一直是 0 或 0xFFFFFF先查接线和供电再查 SCK 和 DT 是否接反。4.2 OLED 显示刷新与重量格式化OLED 用 SSD1306I2C 地址通常 0x78。显示内容分三行第一行显示重量数值第二行显示单位g/kg第三行显示状态稳定/不稳定/超载。重量格式化时注意分度值1g 分度显示整数0.1g 分度显示一位小数。// 重量格式化到字符串根据分度值决定小数位 void format_weight(float weight, char *buf) { if (weight 1000.0f) { sprintf(buf, %.0f g, weight); // 1g 分度 } else { sprintf(buf, %.2f kg, weight / 1000.0f); // 超过 1kg 切 kg } }刷新频率控制在 5Hz 左右太快会闪太慢响应迟钝。每次刷新前判断重量变化是否超过 1 个分度值没超过就不刷减少 I2C 占用。4.3 按键处理与去皮逻辑三个按键用定时器 10ms 扫描一次做 20ms 消抖。去皮逻辑按下去皮键时把当前滤波值赋给offset重量归零。注意去皮后如果重量为负比如拿走了容器显示负值还是归零通常的做法是显示负值提示用户容器已拿走。// 去皮将当前滤波值设为新的零点 void tare(void) { scale.offset (int32_t)scale.filtered; scale.weight 0; // 保存到 Flash flash_save_offset(scale.offset); }校准模式通过长按校准键 3 秒进入然后提示放砝码放好后按确认键计算scale并保存。校准流程要有超时退出防止用户误入后卡死。5. 避坑与常见问题排查5.1 数值跳动大末位一直闪现象空载时显示 0g 到 3g 之间来回跳放上砝码后读数也不稳。原因HX711 的供电噪声、传感器信号线太长、滤波参数太激进或太保守。常见的是用 STM32 的 3.3V 直接给 HX711 供电而 HX711 的 AVDD 建议 5V3.3V 下内部 PGA 工作不正常。解决HX711 的 AVDD 和 DVDD 都接 5V传感器激励也用 5V。信号线用屏蔽线且尽量短。滤波窗口从 10 加到 20alpha从 0.2 降到 0.1。如果还跳在 HX711 的 AVDD 和 AGND 之间并 10μF 和 0.1μF 电容。5.2 标定后小重量准大重量偏差大现象用 100g 砝码标定称 100g 准但称 2kg 时显示 1.95kg。原因标定砝码太小斜率误差被放大。或者传感器本身非线性在大量程时输出偏离直线。解决换用接近满量程的砝码重新标定。如果传感器非线性明显做三点标定20%、50%、80% 量程各标一次用分段线性或最小二乘拟合。代码里把scale和offset换成查表加插值。5.3 按键偶尔失灵或连击现象按一次去皮连续触发多次或者按了没反应。原因消抖时间不够或者按键扫描被 OLED 刷新阻塞。I2C 刷新 OLED 时如果用了硬件 I2C 的阻塞模式一次刷新可能几毫秒期间按键扫描停摆。解决消抖用 20ms 定时器扫描状态机实现检测按下 → 延时 20ms → 确认按下 → 等待释放 → 确认释放。OLED 刷新改用 DMA 或分多次写避免长时间占用 CPU。5.4 上电后重量不为零需要手动去皮现象每次上电显示几克到几十克按去皮才归零。原因零点偏移没有保存或者保存的偏移和当前传感器状态不一致。传感器有温漂冷启动和热稳定后零点不同。解决上电时先读 Flash 里的offset然后连续采 20 个点取平均作为当前零点如果和 Flash 里的偏差超过阈值比如 50 个 count就用当前值更新offset并保存。这样既保留了历史标定又适应了温漂。5.5 超载报警不触发或误触发现象放 6kg 砝码在 5kg 量程的秤上不报警或者正常称 4kg 就报警。原因超载阈值设成了固定原始值但标定后scale变了原始值和重量的对应关系变了。解决超载判断用标定后的重量值阈值设为满量程的 110%。代码里在重量计算后判断if (weight MAX_CAPACITY * 1.1) alarm_on();。同时加迟滞比如超过 110% 报警降到 105% 以下才解除防止在阈值附近抖动。6. 验收与答辩怎么证明这台秤真的能用验收不是把秤往桌上一放说“你看能称”而是要有可复现的测试步骤和量化指标。我一般会准备一套验收流程从零点、线性度、重复性、响应时间四个维度打分。6.1 验收测试项与通过标准测试项测试方法通过标准零点漂移空载连续观察 5 分钟显示值波动不超过 ±1 个分度线性度分别放 20%、40%、60%、80%、100% 量程砝码各点误差不超过 ±1 个分度重复性同一砝码反复加载卸载 10 次10 次读数极差不超过 2 个分度响应时间从放上砝码到显示稳定不超过 2 秒超载报警放 110% 量程砝码蜂鸣器响显示超载提示去皮功能放容器后按去皮再放砝码显示砝码净重误差同上测试时砝码要用标准砝码没有的话用已知重量的物品代替但要在报告里说明。每个测试项至少做 3 组数据取平均。6.2 答辩时怎么讲清楚设计逻辑答辩最怕被问“为什么用 HX711 不用内部 ADC”或者“滤波参数怎么定的”。提前准备好三句话第一句讲信号量级——传感器满量程输出 5mV1g 对应 1μV内部 ADC 分辨不出来第二句讲 HX711 的 PGA 和 24 位分辨率刚好匹配第三句讲滤波参数是实测调出来的窗口 10 和 alpha 0.2 是在跳动和响应速度之间取的平衡。如果评委问“如果传感器坏了怎么排查”按信号链从后往前说先短接 HX711 的 A 和 A-看读数是否接近零再测传感器四线电阻输入输出端各约 1kΩ最后查供电和焊接。这套排查顺序能体现你真正调过硬件不是只跑了仿真。6.3 从验收反推设计改进验收时如果发现线性度在大量程偏差大说明两点标定不够下一版加三点标定。如果响应时间超过 2 秒把滤波窗口从 10 降到 6或者提高 HX711 输出速率到 80Hz。如果零点漂移大加温度补偿——在传感器附近贴一个 NTC 热敏电阻用 STM32 的 ADC 读温度做一阶补偿。我自己的习惯是每次交付前把验收测试表打印出来逐项打勾数据手写在旁边。答辩时这张表比任何 PPT 都有说服力。从那以后我每次做硬件项目都强制走一遍“零点→线性→重复→响应→报警”的验收流程少一步心里都不踏实。希望这套方案能帮到你需要完整工程和原理图的话按文末方式获取就行。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑