目录
[2.1 硬件清单:](#2.1 硬件清单:)
[2.2 功能介绍:](#2.2 功能介绍:)
[资料获取 查看主页介绍:兆龙电子单片机设计](#资料获取 查看主页介绍:兆龙电子单片机设计)
一、设计背景和意义
1.1设计背景:
在日常家庭称重、商超零售计价、快递物流称重、工业小件称重及健康体脂监测场景中,重量实时精准测量、数据便捷记录、智能计价与便携使用是核心需求。传统称重设备存在明显局限:一方面,高端工业级 / 专业级称重设备(如高精度电子天平、定制化智能称重平台、多参数工业称重系统)功能虽全但成本高昂,体积大且操作复杂,依赖专业人员调试与维护,难以普及到普通家庭、小型商超及快递驿站等日常场景,且设备兼容性差,数据无法与个人移动终端、商超收银系统联动,更换或升级成本高,无法灵活满足不同人群(如家庭用户、商超店员、快递从业者)的称重管理需求;另一方面,普通简易称重装置(如机械弹簧秤、单功能简易电子秤、传统台秤)虽操作简单、价格低廉,但功能单一,仅能获取基础重量数值,缺乏高精度校准、智能计价、数据长期存储、体脂等附加健康参数分析及异常称重提醒(如超重、称重不稳)等功能,无法满足现代化称重场景下对重量精准监测、智能高效管理的需求。
现有关称重方案还存在功能割裂与集成度低的问题:部分高端称重设备虽具备多维度数据采集与分析功能,但依赖复杂的软硬件架构与专业维护,后期使用成本高,难以覆盖预算有限的普通消费群体或基层商用场景;而低成本称重装置又在功能完整性与智能化上存在欠缺,无法实现重量数据与移动 APP、商超收银平台的实时联动,导致称重数据误差偏大、无法追溯、个性化需求(如家庭健康体重记录、商超商品计价)无法满足等问题,无法为用户重量趋势分析(如健康体重管理)及商户高效运营(如快速计价对账)提供数据支撑。基于此,本设计以 STM32 单片机为核心,融合高精度称重与辅助模块(如压力传感器、称重放大模块、温度补偿模块、体脂检测辅助模块)、LCD 显示模块、数据存储模块及蓝牙通信与异常报警模块,构建低成本、高集成度的物联网智能数字电子秤系统,以解决传统称重设备精度不足、智能化程度低、功能单一及称重管理效率低的问题。
1.2设计意义:
从使用体验与称重管理效率角度,该系统突破了传统称重设备的局限:一是实现了多维度测量与多功能联动(如支持重量精准测量、自动计价、温度补偿、体脂等健康参数同步检测,联动蓝牙通信模块、异常报警模块),无需用户手动换算或专业人员现场调试校准,减少称重数据采集的繁琐性与人工计算的误差率;二是配备 LCD 实时显示模块,直观呈现当前重量数值、商品单价、总价、体脂率及称重状态(稳定 / 不稳定),同时支持数据自动存储(可通过蓝牙传输至移动 APP / 商超收银平台 / 家庭健康管理平台),方便用户与商户长期追溯称重数据,也为用户分析体重变化趋势、商户实现高效对账结算及优化进销存管理方案提供完整数据支撑;三是新增异常预警与自动调控功能,当监测到某项参数超出合理范围(如称重超重、重量数据波动过大、体脂率超出健康阈值),系统自动触发声光报警(同时向绑定的商户终端 / 家庭健康终端发送预警信息),并联动计价模块暂停自动计价、给出放置平稳等提示,无需人工干预即可及时规避称重失误风险,大幅提升了称重操作的便捷性与时效性。
从技术实践与成本控制角度,本设计以 STM32 单片机为核心,充分利用其低功耗、高性价比的优势,搭配低成本的高精度称重模块及通用外围模块,在保证测量精度(重量监测准确率可控制在 0.1g/0.1kg 级,数据响应时间可控制在 0.5 秒以内)的前提下,有效降低了系统整体成本,相比同功能的高端工业级 / 专业级称重设备成本降低 40%-60%,更易普及到普通家庭、小型商超、快递驿站及社区健康服务站等场景。同时,系统支持模块化扩展(如后续可新增语音播报计价功能、多人健康体重档案管理功能、商超条码联动计价功能),为后续功能升级预留了空间,具备良好的灵活性与可扩展性。
**二、**实物展示
下方为实物演示视频
下方为实物展示图片

三、硬件功能介绍
2.1 硬件清单:
- STM32F103C8T6
- LCD1602显示
- HX711称重模块
- 矩阵键盘
- 蓝牙模块
- 蜂鸣器报警
- 降压电路
2.2 功能介绍:
(1)液晶显示当前重量大小、单价和总价
(2)按键可以设置当前物品单价
(3)具有去皮清零和删除单价功能
(4)按确认按键液晶显示当前重量,单价,总价
(5)屏幕上的数据上传到蓝牙APP,可设置单价、去皮清零和删除单价功能
四、软件设计流程图

五、硬件PCB展示

六、软件主函序展示
#include "sys.h"
#include "GPIO.h"
#include "LCD1602.h"
#include "delay.h"
#include "sys.h"
#include "stdio.h"
#include "usart.h"
#include "timer.h"
#include "string.h"
#include "hx711.h"
#include <string.h>
#include "stdarg.h"
#include "stdlib.h"
#include <stdlib.h>
#include <stdbool.h>
#define uchar unsigned char
#define uint unsigned int
//定义量程系数
#define RATIO 0.0047048 //
//定义标识
volatile unsigned char FlagKeyPress = 0; //有键按下标志,处理完毕清0
volatile unsigned char FlagSetPrice = 0; //价格设置状态标志,设置好为1。
//显示用变量
int Counter;
int i, iTemp;
//称重用变量
unsigned long FullScale; //满量程AD值/1000
unsigned long AdVal; //AD采样值
unsigned long weight; //重量值,单位g
unsigned long price; //单价,长整型值,单位为分
unsigned long money; //总价,长整型值,单位为分
unsigned long pre_weight; //重量值,单位g
unsigned long pre_money;
//键盘处理变量
unsigned char keycode;
unsigned char DotPos; //小数点标志及位置
unsigned char SendString[20]; //向蓝牙发送的显示信息
unsigned char sendFlag=0;
extern vu16 USART1_RX_STA;
/*延时*/
void delay(int i)
{
int j,k;
for(j=0; j<i; j++)
for(k=0; k<500; k++);
}
//重新找回零点,每次测量前调用
void To_Zero()
{
FullScale=ReadCount();
price=0;
}
//显示单价,单位为元,两位整数,一位小数
void Display_Price()
{
LCD1602_write_com(0x8c);
LCD1602_write_data(price/100 + 0x30);
LCD1602_write_data(price%100/10 + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(price%10 + 0x30);
}
//显示重量,单位kg,一位整数,三位小数
void Display_Weight()
{
LCD1602_write_com(0x83);
LCD1602_write_data(weight/1000 + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(weight%1000/100 + 0x30);
LCD1602_write_data(weight%100/10 + 0x30);
LCD1602_write_data(weight%10 + 0x30);
}
//显示总价,单位为元,三位整数,一位小数
void Display_Money()
{
if (money>9999) //超出显示量程
{
LCD1602_write_com(0x80+0x40+4);
LCD1602_write_word("---.-");
return;
}
if (money>=1000)
{
LCD1602_write_com(0x80+0x40+4);
LCD1602_write_data(money/1000 + 0x30);
LCD1602_write_data(money%1000/100 + 0x30);
LCD1602_write_data(money%100/10 + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(money%10 + 0x30);
}
else if (money>=100)
{
LCD1602_write_com(0x80+0x40+4);
LCD1602_write_data(0x20);
LCD1602_write_data(money%1000/100 + 0x30);
LCD1602_write_data(money%100/10 + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(money%10 + 0x30);
}
else if(money>=10)
{
LCD1602_write_com(0x80+0x40+4);
LCD1602_write_data(0x20);
LCD1602_write_com(0x80+0x40+5);
LCD1602_write_data(0x20);
LCD1602_write_data(money%100/10 + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(money%10+ 0x30);
}
else
{
LCD1602_write_com(0x80+0x40+4);
LCD1602_write_data(0x20);
LCD1602_write_com(0x80+0x40+5);
LCD1602_write_data(0x20);
LCD1602_write_com(0x80+0x40+6);
LCD1602_write_data(0 + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(money%10 + 0x30);
}
}
//数据初始化
void Data_Init()
{
price = 0;
DotPos = 0;
}
//按键响应程序,参数是键值
//返回键值:
// 7 8 9 10(清0)
// 4 5 6 11(删除)
// 1 2 3 12(未定义)
// 14(未定义) 0 15(.) 13(确定价格)
void KeyPress(uchar keycode)
{
switch (keycode)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
//目前在设置整数位,要注意price是整型,存储单位为分
if (DotPos == 0)
{
//最多只能设置到千位
if (price<100)
{
price=price*10+keycode*10;
}
}
//目前在设置小数位
else if (DotPos==1) //小数点后第一位
{
price=price+keycode;
DotPos=2;
}
Display_Price();
break;
case 10: //清零键
To_Zero();
Display_Price();
FlagSetPrice = 0;
DotPos = 0;
break;
case 11: //删除键,按一次删除最右一个数字
// if (DotPos==2)
// {
// price=price/10;
// price=price*10;
// DotPos--;
// }
// else if (DotPos==1)
// {
// price=price/100;
// price=price*10;
// DotPos--;
// }
// else if (DotPos==0)
// {
// price=price/100;
// price=price*100;
//
// }
price=0;
DotPos=0;
FlagSetPrice = 0;
Display_Price();
break;
case 13: //确认键
FlagSetPrice = 1;
DotPos=0;
break;
case 15: //小数点按下
DotPos = 1; //小数点后第一位
break;
}
}
七、单片机实物资料
