1. 项目概述:基于51单片机的4挡电子秤设计
这个项目是我去年帮朋友做的一个小型电子秤方案,核心需求是用最基础的51单片机实现一个具备4种称重模式的低成本电子秤。当时朋友开烘焙工作室需要能切换克、盎司、磅和公斤四种单位的称重设备,但市面上的多单位电子秤价格都在300元以上。我们用STC89C52RC做主控,配合HX711称重模块,最终BOM成本控制在80元以内。
这种方案特别适合需要定制化称重功能的小型商户或DIY爱好者。相比成品电子秤,自己开发的优势在于可以自由定义单位切换逻辑、显示界面和校准方式。比如我们后来就应客户要求增加了"自动去皮归零"和"超重蜂鸣提醒"的功能。
2. 硬件设计详解
2.1 核心元件选型
主控芯片选用STC89C52RC主要基于三点考虑:
- 内置4KB Flash完全够用(最终编译后代码仅2.3KB)
- 有标准的40引脚DIP封装,方便手工焊接
- 支持5V供电,与HX711模块电平匹配
称重传感器用的是常见的5kg量程悬臂梁式传感器(型号:HBM-C3),单价仅15元。这类传感器采用惠斯通电桥原理,输出mV级差分信号,需要配合24位ADC使用。
ADC模块选用HX711是因为:
- 集成PGA(可编程增益放大器),放大倍数可选128或64
- 自带稳压电路,可直接从5V取电
- 两线制串行接口,仅需占用单片机两个IO口
- 单价不到5元,性价比极高
2.2 电路原理图设计
电源部分采用AMS1117-3.3V给HX711供电,主控仍用5V供电。这样设计有两个好处:
- HX711工作在3.3V时噪声更低
- 5V和3.3V之间通过10K电阻分压实现电平匹配
称重传感器接口要注意:
- 必须使用屏蔽线连接,我们选用RVVP 3×0.3mm²
- 传感器输出端要加0.1μF滤波电容
- EXC+和EXC-之间建议并联100Ω电阻提高稳定性
键盘电路采用4×4矩阵布局,包含:
- 单位切换键(克/盎司/磅/公斤循环)
- 去皮功能键
- 校准模式键
- 数字键0-9(预留功能扩展)
显示部分使用LCD1602,通过P0口直接驱动。注意要加10K上拉电阻,否则显示会不正常。
3. 软件设计流程
3.1 主程序流程图
程序采用状态机设计,主要状态包括:
- 上电自检(检测传感器和HX711)
- 待机状态(显示当前单位和零位值)
- 称重状态(动态显示重量值)
- 校准状态(分空载和满载两步)
关键算法是滑动平均滤波:
c复制#define FILTER_LEN 10
unsigned long filter_buf[FILTER_LEN];
long get_filtered_adc() {
static int index = 0;
long sum = 0;
filter_buf[index++] = HX711_Read();
if(index >= FILTER_LEN) index = 0;
for(int i=0; i<FILTER_LEN; i++) {
sum += filter_buf[i];
}
return sum/FILTER_LEN;
}
3.2 单位转换算法
四种单位的转换关系:
- 1 盎司(oz) = 28.3495 克(g)
- 1 磅(lb) = 453.592 克(g)
- 1 公斤(kg) = 1000 克(g)
在代码中采用定点数运算提高效率:
c复制// 单位转换系数(Q16格式)
#define OZ_RATE 185722 // 28.3495 * 65536
#define LB_RATE 29724672 // 453.592 * 65536
int convert_unit(long raw_g, int unit) {
switch(unit) {
case 0: return raw_g; // 克
case 1: return (raw_g * 65536L) / OZ_RATE; // 盎司
case 2: return (raw_g * 65536L) / LB_RATE; // 磅
case 3: return raw_g / 1000; // 公斤
}
return 0;
}
4. Proteus仿真要点
4.1 传感器信号模拟
在Proteus中可以用POT-HG滑动变阻器模拟称重传感器输出:
- 创建分压电路:VCC → POT → GND
- 中间抽头接HX711的AVDD
- 设置POT阻值为10KΩ
调试时发现Proteus的HX711模型有个坑:它默认是连续转换模式,而实际芯片需要外部触发。解决方法是在代码中增加延时:
c复制void HX711_Init() {
PD_SCK = 0;
Delay_ms(100); // 关键!等待HX711稳定
}
4.2 虚拟终端调试
建议添加Virtual Terminal监控串口输出:
- 波特率设为9600
- 在代码中打印关键变量:
c复制printf("Raw: %ld, Filtered: %ld, Weight: %d\r\n",
adc_raw, adc_filtered, weight);
- 可以实时观察滤波效果和单位转换结果
5. 实际制作中的经验技巧
5.1 机械结构设计
称重平台要用刚性材料(我们用的3mm铝板),支撑点要成三角形分布。实测发现:
- 塑料平台会有蠕变误差(半小时漂移约0.3%)
- 四脚支撑容易导致"跷跷板"效应
- 最佳方案是中间单点支撑+外围三点限位
5.2 校准注意事项
校准分两步:
- 空载校准:放上托盘后按TARE键
- 满载校准:放已知重物(建议用标准砝码)
校准算法:
c复制// 校准参数存储到EEPROM
typedef struct {
long offset; // 空载AD值
float scale; // 满量程比例系数
} CalibData;
void do_calibration(long adc_empty, long adc_full, float known_weight) {
CalibData cd;
cd.offset = adc_empty;
cd.scale = known_weight / (adc_full - adc_empty);
EEPROM_Save(0, &cd, sizeof(cd));
}
5.3 抗干扰措施
现场测试时发现两个典型问题:
- 开关电源干扰:表现为末位数跳动±3
- 解决方法:在HX711的AVDD和AGND间加10μF钽电容
- 静电干扰:触摸外壳时显示乱跳
- 解决方法:外壳接大地,传感器与金属外壳绝缘
6. 性能优化方向
6.1 提高采样速率
默认情况下HX711工作在10Hz会引入明显延迟。可以通过修改硬件获得80Hz采样率:
- 将HX711的XI引脚接VCC(选择内部晶振)
- 在初始化时设置速率位:
c复制PD_SCK = 1; Delay_us(1);
PD_SCK = 0; // 切换到通道A,增益128,80Hz
6.2 增加温度补偿
称重传感器有约0.02%/℃的温度系数。改进方案:
- 添加DS18B20温度传感器
- 建立温度-误差对照表
- 实时补偿:
c复制float temp = DS18B20_GetTemp();
float comp = 1.0 + (temp - 25.0) * 0.0002;
weight_compensated = weight_raw * comp;
6.3 低功耗设计
如果改用电池供电,可以:
- 选用STC15W系列低功耗单片机
- 称重间歇时关闭HX711电源(需增加MOS管控制)
- LCD改用OLED屏(省电且对比度高)
