基于51单片机与HX711的电子秤设计:从传感器原理到嵌入式实现
2026/9/3 5:28:43 网站建设 项目流程

简介:本资源是一套面向电子工程初学者与单片机实践者的完整电子秤开发方案,基于经典51单片机实现5kg量程的高实用性称重系统,涵盖去皮校准、传感器信号采集、A/D转换、LCD1602实时显示等核心功能,适用于课程设计、毕业设计及嵌入式入门实训。压缩包共100个文件,含10个C源码文件(主控逻辑与传感器驱动)、10个头文件(模块化接口定义)、10个汇编列表(lst)与目标文件(obj),以及Keil工程配置文件(uvproj/uvopt)、Hex烧录文件、Proteus仿真工程(pdsprj)和调试备份文件(bak),整体大小733KB,结构清晰,便于分模块学习与调试。已有788人下载学习,配套代码可直接编译运行,仿真文件支持在Proteus中验证硬件逻辑与程序交互效果,显著降低实物调试门槛,是掌握传感器应用、单片机外设驱动与人机交互开发的优质实践素材。

1. 项目概述:从零到一打造一台自己的电子秤

最近在整理工作室,翻出来一堆当年玩单片机剩下的“古董”,其中就有几片经典的STC89C52。看着这些老朋友,突然就想动手做个实用的小玩意儿,既能重温一下51单片机的开发流程,又能解决点实际问题。于是,一个基于51单片机的电子秤项目就这么提上了日程。这玩意儿听起来简单,不就是称个重嘛,但真要从头到尾自己设计、编程、调试,把一堆分立元件变成一台能稳定、准确显示重量的设备,里面门道可不少。它完美融合了模拟电路(传感器信号处理)、数字电路(单片机控制)和人机交互(显示与输入)的知识点,是个非常经典的嵌入式系统入门与进阶练手项目。

这个电子秤的核心功能,就是通过电阻应变式压力传感器,将物体的重量转换成微弱的电压信号,经过放大和模数转换后,由51单片机进行处理,最终在数码管或液晶屏上直观地显示出来。它适合所有对单片机感兴趣的朋友,无论是刚学完郭天祥老师视频想找项目练手的新手,还是想深入理解传感器应用和信号处理细节的进阶玩家。通过这个项目,你不仅能巩固单片机编程、定时器、中断、AD转换等核心知识,更能亲手触摸到从物理量到数字量的完整转换链条,这种成就感是单纯看教程无法比拟的。接下来,我就把自己从构思到实现的全过程,包括踩过的坑和总结的经验,毫无保留地分享出来。

2. 核心思路与方案选型:为什么是“51+HX711”这个黄金组合?

做电子秤,首先得确定技术路线。市面上方案很多,有用高级ARM芯片配24位ADC的,也有用现成的称重模块的。但我这次的目标很明确:在保证基本精度和稳定性的前提下,最大限度地利用经典51单片机的资源,降低成本和复杂度,突出学习价值。经过一番权衡,我选择了“STC89C52 + HX711 AD模块 + 电阻应变片传感器”这套堪称经典的组合。

2.1 主控芯片:为何坚守STC89C52?

也许有人会问,现在STM32那么强大,为什么还用老旧的51?这里有几个很实际的考虑。首先,学习成本与资源丰富度。51单片机的架构简单,指令集易学,资料浩如烟海,从郭天祥的教程到无数课程设计案例,几乎你遇到的任何基础问题都能找到答案。对于初学者或重温者来说,这能极大降低入门门槛,让你把精力集中在电子秤的应用逻辑上,而不是纠缠于复杂的外设配置。其次,项目需求匹配度。电子秤的核心任务是读取AD值、进行标定计算、驱动显示。这些任务对主频和计算能力要求并不高,51单片机完全能够胜任。最后是情怀与挑战。在资源受限的平台上完成一个实用项目,更能锻炼编程功底和系统设计能力,比如如何优化代码节省ROM/RAM,如何用定时器模拟更复杂的时序等。

当然,我选择的STC89C52是增强型51,比传统的AT89C51多了内部EEPROM(用于保存标定参数)、更多的RAM和Flash,还有额外的定时器,实用性大增。它就像一把可靠的老钳子,干这个活儿正合适。

2.2 重量采集核心:HX711模块为何是首选?

这是整个系统的精度担当。早期方案常用单片机自带的10位或12位ADC(如STC12C5A60S2自带10位ADC)直接连接传感器桥式电路。但实测下来问题很多:传感器输出的是毫伏级差分信号,需要高精度、高共模抑制比的仪表放大器进行放大,电路设计、调零、温漂处理都很麻烦,对新手极不友好。

HX711是一款专为电子秤设计的24位A/D转换器芯片。它把最难的部分都做好了:内部集成了可编程低噪声放大器,增益可选128或64,能直接接收应变片传感器的微弱信号;提供了稳定的片上时钟,无需外部晶振;采用差分输入,有效抑制共模干扰;最重要的是,它的24位分辨率带来了极高的理论精度。我们只需要通过简单的两根线(SCK和DOUT)与单片机进行串行通信,就能读取到稳定的AD值,极大简化了硬件设计和软件驱动。可以说,选用HX711,是平衡性能、成本和开发难度的最优解。

2.3 传感器与显示方案选择

传感器方面,我选用最常见的铝合金悬臂梁式电阻应变片传感器,量程有5kg、10kg等多种可选。这种传感器价格便宜,结构简单,其上的应变片组成惠斯通电桥,受力时桥臂电阻变化,输出差分电压。购买时通常已焊接好,并引出四条线(电源正、电源负、信号正、信号负),直接插到HX711模块上即可。

显示方案上,为了兼顾经典性和可读性,我选择了4位一体共阳数码管驱动显示。虽然LCD1602液晶屏显示字符更丰富,但数码管的驱动更能体现单片机对IO口的直接操作和动态扫描原理,视觉上也更有“仪器感”。通过74HC595串行转并行芯片驱动,可以节省大量单片机IO口。如果追求更友好的界面,切换成LCD12864显示图形化内容也是可行的升级方向。

3. 硬件系统设计与关键电路解析

画原理图是项目从想法走向实物的关键一步。硬件设计的目标是稳定、可靠、易于调试。我的核心系统框图很简单:传感器 -> HX711模块 -> 51单片机 -> 显示与按键模块。但每个环节都有细节需要注意。

3.1 电源电路设计:稳定是一切的前提

电子秤对电源噪声比较敏感,尤其是给HX711和传感器供电的部分。我采用LM7805三端稳压芯片将外部9V或12V适配器电源稳压到5V。这里有个关键点:必须在7805的输入和输出端就近并联滤波电容。我在输入端加了一个100μF的电解电容滤低频,一个0.1μF的瓷片电容滤高频;输出端同样配置。此外,单独用一路7805(或使用低压差稳压器LD1117-5.0)为模拟部分(HX711和传感器)供电,或者在数字电源5V后使用磁珠或0Ω电阻隔离,再经LC滤波(如一个10μH电感和0.1μF电容)后供给HX711,能有效减少数字电路噪声通过电源干扰敏感的模拟信号。

注意:传感器和HX711的供电电压(AVDD)直接影响其灵敏度和零点输出。务必确保其稳定在5V±0.1V以内。如果使用USB供电,由于电脑USB口电压可能波动,建议还是使用独立的稳压电源适配器。

3.2 单片机最小系统与外围电路

STC89C52的最小系统包括:复位电路(10uF电容+10K电阻构成上电复位)、晶振电路(11.0592MHz晶振+两个22pF负载电容,这个频率便于产生标准的串口波特率)、EA引脚接VCC(使用内部程序存储器)。为了调试方便,我引出了串口引脚(P3.0/RXD, P3.1/TXD)连接一个CH340G USB转TTL模块,这样既能下载程序,也能在调试时通过串口打印内部数据,比如实时的AD值、计算出的重量等,对于标定和排查问题至关重要。

按键电路设计为独立按键,一端接地,另一端接单片机IO口并上拉到VCC。我设置了三个键:“去皮”键(在已有重量下归零)、“标定”键(进入重量标定模式)、“单位切换”键(克/千克/盎司切换)。按键引脚通常使能内部上拉电阻或外部上拉,程序里采用软件消抖处理。

3.3 HX711模块与传感器的连接

这是硬件连接中最需要细心的一步。HX711模块通常有4个输入引脚:VCC、GND、DT(DOUT)、SCK;以及4个传感器接口:E+、E-、A+、A-。

  • 供电:VCC接模拟5V,GND接模拟地。
  • 数据接口:DT接单片机任意IO口(如P1.0),SCK接另一IO口(如P1.1)。
  • 传感器连接:传感器的红线(电源+)接E+,黑线(电源-)接E-;白线(信号+)接A+,绿线(信号-)接A-。如果接反,测量值会随重量增加而减小

模块上的两个贴片电阻(R1, R2)是用于设置内部放大器增益的。焊上R1(标记为128)则增益为128,适用于小量程(如1kg以下);焊上R2(标记为64)则增益为64,适用于较大量程。我用的10kg传感器,选择增益64。

4. 软件程序设计:驱动、算法与逻辑

软件是电子秤的灵魂,需要处理数据采集、滤波、标定、显示和按键响应。程序采用模块化设计,主要包括:HX711驱动、重量计算算法、数码管显示、按键扫描和主循环逻辑。

4.1 HX711驱动程序编写

与HX711的通信是简单的同步串行通信。其时序要求严格,需根据数据手册编写精准的延时。核心函数是Read_HX711()

// 假设DT接P1^0, SCK接P1^1 sbit HX711_DOUT = P1^0; sbit HX711_SCK = P1^1; // 延时函数,需根据实际晶振频率微调 void Delay__hx711_us(void) { _nop_(); _nop_(); _nop_(); _nop_(); } // 读取HX711的24位AD值(补码形式) unsigned long Read_HX711(void) { unsigned long count = 0; unsigned char i; HX711_DOUT = 1; // 确保DOUT为输入状态 Delay__hx711_us(); HX711_SCK = 0; // 等待HX711准备好(DOUT变低) while(HX711_DOUT == 1); // 读取24位数据 for(i=0; i<24; i++) { HX711_SCK = 1; Delay__hx711_us(); count = count << 1; // 左移,先读高位 HX711_SCK = 0; Delay__hx711_us(); if(HX711_DOUT == 1) { count++; } } // 再发送一个脉冲,设置下一次读取的通道和增益 HX711_SCK = 1; Delay__hx711_us(); HX711_SCK = 0; Delay__hx711_us(); // 将补码转换为原码(对于正数相同,对于负数需处理) // 由于重量通常不为负,且我们主要关心差值,有时可直接使用 // count = count ^ 0x800000; // 如果需要进行符号转换 return count; }

实操心得:这里的延时Delay__hx711_us()非常关键。太快可能导致数据读取错误,太慢则影响称重刷新率。最好用示波器或者通过反复测试,确定一个稳定的值。我的经验是,在11.0592MHz晶振下,用几个_nop_()空操作指令构成的延时通常就能工作。如果读数偶尔跳变极大,首先检查时序延时。

4.2 数字滤波与重量计算算法

直接从HX711读出的AD值存在随机噪声,必须进行滤波。我采用了一种简单有效的复合滤波方法:连续采样10次,去掉一个最大值和一个最小值,剩下的8次取算术平均。这种方法既能抑制脉冲干扰,又能保证一定的实时性。

unsigned long Get_Weight_AD(void) { unsigned long ad_value[10]; unsigned long max = 0, min = 0xFFFFFFFF, sum = 0; unsigned char i; for(i=0; i<10; i++) { ad_value[i] = Read_HX711(); // 短暂延时,避免两次读取间隔太短 Delay_ms(5); } // 找最大值和最小值 for(i=0; i<10; i++) { if(ad_value[i] > max) max = ad_value[i]; if(ad_value[i] < min) min = ad_value[i]; sum += ad_value[i]; } // 减去最大值和最小值后求平均 sum = sum - max - min; return (sum >> 3); // 除以8,用右移运算提高效率 }

得到滤波后的AD值后,需要将其转换为重量。这需要标定。标定的原理是线性拟合:重量 = K * (当前AD值 - 零点AD值)

  1. 零点标定:空载时,记录一个AD值作为AD_ZERO
  2. 满量程标定:放置一个已知重量的标准砝码(如500g),记录此时的AD值AD_WEIGHT
  3. 计算系数KK = 标准重量 / (AD_WEIGHT - AD_ZERO)

AD_ZEROK保存在单片机的EEPROM中(STC89C52有内部EEPROM),每次上电读取。计算重量的函数如下:

float Calculate_Weight(unsigned long current_ad) { long ad_diff; float weight; // 防止负数处理 if(current_ad > ad_zero) { ad_diff = current_ad - ad_zero; } else { ad_diff = 0; } weight = (float)ad_diff * scale_factor; // scale_factor 即 K return weight; }

4.3 数码管动态显示与按键处理

显示部分采用定时器中断驱动动态扫描,保证刷新流畅。定时器0设置为1ms中断一次,在中断服务程序中依次点亮一位数码管,并显示对应数字。主程序负责计算重量并更新显示缓冲区。

按键处理在主循环中采用状态机模型,实现短按、长按功能。例如,“去皮”键短按将当前重量值设为新的零点(临时性,重启失效);长按3秒则进入标定模式,按照提示依次进行零点标定和砝码标定,并将新参数存入EEPROM。

void main() { unsigned long current_ad; float weight_gram; Sys_Init(); // 系统初始化:定时器、中断、IO口、读取EEPROM参数 while(1) { // 1. 读取重量AD值 current_ad = Get_Weight_AD(); // 2. 计算重量(克) weight_gram = Calculate_Weight(current_ad); // 3. 更新显示缓冲区(将浮点数转换为4位整数,处理小数点) Update_Display_Buffer(weight_gram); // 4. 扫描按键并执行相应功能 Key_Scan_Process(); // 5. 适当的延时,控制主循环频率 Delay_ms(100); // 每秒更新10次重量显示,兼顾响应和稳定 } }

5. 系统标定与精度调试实战

标定是电子秤能否可用的决定性步骤。理论很简单,但实操中有很多技巧。

5.1 分步标定流程

我设计了一个通过按键触发的交互式标定流程:

  1. 长按“标定”键3秒,进入标定模式,数码管显示“CAL”。
  2. 零点标定:确保秤盘空载,稳定后按一次“标定”键,单片机记录当前AD值为AD_ZERO,显示“0-PASS”。
  3. 满量程标定:放置已知重量的标准砝码(例如500.0g)。等待数值稳定(数码管跳动很小),按一次“标定”键,单片机记录当前AD值为AD_WEIGHT,并计算scale_factor = 500.0 / (AD_WEIGHT - AD_ZERO)
  4. 保存并退出:数码管显示“SAVE”,自动将AD_ZEROscale_factor写入EEPROM,然后重启系统。

关键技巧:标定用的砝码最好接近你常用量程的中间值或最大值。例如,你的秤量程是1000g,用500g砝码标定比用100g砝码在满量程端误差更小。砝码的精度直接决定标定精度,建议使用M2级或以上的标准砝码。

5.2 提高稳定性和精度的技巧

  1. 预热:系统上电后,让HX711和传感器工作5-10分钟再进行标定或精确称量,使其内部温度稳定,减少温漂影响。
  2. 多次标定取平均:在标定步骤中,可以程序上自动连续采样多次(如10次)记录零点或砝码值,然后取平均,这样得到的标定参数更可靠。
  3. 软件滤波进阶:除了采样时滤波,对最终计算出的重量值也可以进行滑动平均滤波或一阶低通数字滤波,让显示值更平滑。
    // 一阶低通数字滤波示例 float filtered_weight = 0.9 * filtered_weight + 0.1 * new_raw_weight;
  4. 非线性补偿(进阶):如果对精度要求极高,会发现传感器的输入输出并非完美的直线。可以在多个重量点(如0g, 200g, 500g, 800g, 1000g)进行标定,记录多组AD值,然后在程序中采用分段线性插值或查表法进行补偿,这能显著提升全量程的精度。

6. 常见问题排查与实战心得

在制作过程中,肯定会遇到各种问题。下面是我总结的“故障树”,帮你快速定位。

现象可能原因排查步骤与解决方案
上电后数码管无任何显示1. 电源未接通或短路
2. 单片机未工作(晶振、复位电路)
3. 数码管驱动电路错误
1. 检查电源电压,测量7805输出是否为5V。
2. 用示波器测单片机ALE引脚是否有脉冲(约1/6晶振频率),无则查晶振和复位电路。
3. 检查74HC595连接,测量其输出引脚电平是否随扫描变化。
显示“----”或乱码,重量不变化1. HX711读取失败
2. 传感器或HX711供电异常
3. 传感器连接线错误或断开
1. 用万用表测HX711的VCC是否为稳定5V。
2. 检查传感器四根线是否接对,可尝试交换A+和A-。
3.通过串口打印原始AD值,这是最有效的调试手段。如果AD值始终为0或固定值,检查DT/SCK时序和连接。
显示值一直为01. 标定参数错误(AD_ZERO过大)
2. 传感器未受力或损坏
3. 重量计算函数有误
1. 检查EEPROM读取的AD_ZEROscale_factor是否正确。
2. 空载时打印AD值,用手轻压传感器,看AD值是否变化。不变则可能是传感器或HX711损坏。
3. 检查计算公式,确保(current_ad - ad_zero)不为负。
显示值跳动(不稳定)1. 电源噪声大
2. 机械振动或风吹
3. 滤波算法不足或参数不当
4. HX711外围电路干扰
1. 加强电源滤波,模拟部分独立供电。
2. 将秤放在稳固的台面上,加防震垫。
3. 增加软件采样次数和滤波强度。
4. 检查HX711的电源和地线是否粗短,传感器线是否用屏蔽线且远离数字线路。
称重不准,线性度差1. 标定砝码不准
2. 传感器线性度差或超量程使用
3. 标定过程操作不当(未稳定就按键)
1. 换用更准确的砝码重新标定。
2. 确认物体重量在传感器量程内。尝试用多个砝码点标定,进行非线性补偿。
3. 标定时务必等待显示值完全稳定(至少3-5秒无变化)。

我个人最深刻的体会是:调试时一定要把数据“可视化”。充分利用单片机的串口,把关键的中间变量,比如原始AD值、滤波后的AD值、计算出的重量浮点数,实时打印到电脑的串口助手上。这样,你能清晰地看到每个环节的数据是否正常,是硬件连接问题、时序问题,还是算法逻辑问题,一目了然,效率远超盲目猜测。

另一个心得是关于机械结构。传感器,尤其是悬臂梁式传感器,其安装的平行度、受力点的位置都非常影响测量结果。最好为传感器设计或购买一个简单的承重台和底座,确保力垂直、均匀地施加在传感器的受力点上。自己用亚克力板或木板搭一个,效果会好很多。

最后,这个项目做完后,你收获的不仅仅是一台能用的电子秤。你深入理解了桥式电路、差分信号、高精度ADC、传感器标定、数字滤波等一系列概念,并且用代码将它们变成了现实。这种从物理世界感知信息,经过硬件和软件处理,再反馈到物理世界显示的过程,正是嵌入式系统的精髓所在。你可以在此基础上继续扩展:增加超限报警功能、通过蓝牙模块将重量数据发送到手机APP、做成具有累计和计价功能的厨房秤等等。希望我的这些经验,能帮你少走弯路,顺利点亮属于自己的那台电子秤。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询