标题:
基于51单片机HX711+WT588D智能语音电子秤程序电路原理图设计
[打印本页]
作者:
涛涛涛涛疯人院
时间:
2024-3-6 17:27
标题:
基于51单片机HX711+WT588D智能语音电子秤程序电路原理图设计
本系统采用单片机 + LCD1602液晶 + HX711AD模块 + 5 kg电阻应变式压力传感器 +蜂鸣器+矩阵键盘+WT588D语音模块而成。
1.单片机型号:STC89C52/51、AT89C52/51、AT89S52/51可以任选,都是51单片机。
2.称重传感器采用电子秤专用模拟/数字(A/D)转换器芯片hx711对传感器信号进行调理转换,提供更高的精度。
3.采用液晶LCD1602显示屏显示,第一行显示当前重量(单位为kg),第二行单价和总价(单位为元)。
4.按键具有提示声,具有超量程报警功能当超出压力传感器的量程时蜂鸣器会发出报警声。
5.采用高精度电阻应变式压力传感器,测量量程0 -5kg,测量精度可达3g。
6.采用4*4矩阵键盘进行人机交互,可以实现直接输入单价、删除单价、去皮、清零等功能操作非常方便。
7.采用WT588D语音模块实现语音播报功能。
4*4矩阵键盘定义如下
1 2 3 15(删除键)
4 5 6 14(去皮或是清零)
7 8 9 13(清除单价)
10(未定义) 0 11(未定义) 12(未定义)
键0—9为数字键,用于单价输入。
键13为单价一键清零,按下该键则单价清为0。
键14为去皮键,按下后当前重量清为0。
键15为删除键,当我们单价输入错误时可以逐位删除输错的单价,删除后可以继续输入单价。
Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
截图格式 双击可以打开.png
(99.37 KB, 下载次数: 27)
下载附件
2024-3-6 23:07 上传
带语音.png
(439.64 KB, 下载次数: 23)
下载附件
2024-3-6 23:07 上传
单片机源程序如下:
#include <reg52.h> //调用单片机头文件
#define uchar unsigned char //无符号字符型 宏定义 变量范围0~255
#define uint unsigned int //无符号整型 宏定义 变量范围0~65535
#define ulong unsigned long
sbit rs=P1^0; //寄存器选择信号 H:数据寄存器 L:指令寄存器
sbit rw=P1^1; //寄存器选择信号 H:数据寄存器 L:指令寄存器
sbit e =P1^2; //片选信号 下降沿触发
sbit hx711_dout = P2^1; //hx711 IO口定义
sbit hx711_sck = P2^0; //hx711 IO口定义
sbit beep = P2^7; //蜂鸣器 IO口定义
long weight; //重量变量
unsigned long Weight_Maopi; //皮重变量
#define GapValue 437.0
uchar flag_300ms ; //300毫秒的变量
ulong price,z_price; //单价 总价
uchar flag_p;
uchar menu_1,menu_2; //设置不同参数的变量
/***********************语音模块控制IO口的定义************************/
sbit VRST = P1^3; //复位脚
sbit VBUSY = P1^4; //忙脚
sbit VDATA = P1^5; //数据输入脚
sbit VCS = P1^6; //片选脚
sbit VCLK = P1^7; //时钟脚
/******1ms延时函数***12M晶振**************/
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<120;j++);
}
/***********************语音模块子程序************************/
void Send_threelines(unsigned char addr)
{
unsigned char i;
VRST=0; //复位脚 低电平
VRST=1; //复位脚 高电平
VCS=0; //片选脚 低电平
for(i=0;i<8;i++) //8位的数据 要循环8次1位1位的写入
{
VCLK=0; //时钟脚 低电平
if(addr&0x01 == 0x01)
{
VDATA=1; //数据输入脚 写数据1
}
else
VDATA=0; //数据输入脚 写数据0
addr>>=1; //数据左移一位
VCLK=1; //时钟脚 高电平
}
VCS=1; //片选脚 高电平
while(VBUSY == 0); //忙等待
}
/********************************************************************
* 名称 : delay_uint()
* 功能 : 小延时。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void delay_uint(uint q)
{
while(q--);
}
/********************************************************************
* 名称 : write_com(uchar com)
* 功能 : 1602指令函数
* 输入 : 输入的指令值
* 输出 : 无
***********************************************************************/
void write_com(uchar com)
{
rs=0; //写指令
rw=0; //对1602写操作
P0=com; //P0口对1602写指令数据
delay_uint(25);
e=1; //e=1使能信号
delay_uint(100); //延时一下等1602完成操作
e=0;
}
/********************************************************************
* 名称 : write_data(uchar dat)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/
void write_data(uchar dat)
{
rs=1; //写数据
rw=0; //对1602写操作
P0=dat; //P0口对1602写数据
delay_uint(25);
e=1; //e=1使能信号
delay_uint(100); //延时一下等1602完成操作
e=0;
}
/********************************************************************
* 名称 : write_string(uchar hang,uchar add,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
write_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void write_string(uchar hang,uchar add,uchar *p)
{
if(hang==1)
write_com(0x80+add); //1602写第一行的地址
else
write_com(0x80+0x40+add); //1602写第二行的地址
while(1)
{
if(*p == '\0') break; //\0字符串的结尾标志 break结束while循环 结束写字符
write_data(*p); //写数据
p++; //指针地址加1
}
}
////////////////在指定位置显示指定字符//////////
void write_zifu(uchar hang,uchar add,uchar dat)
{
if(hang==1)
write_com(0x80+add); //1602写第一行的地址
else
write_com(0x80+0x40+add); //1602写第二行的地址
write_data(dat);
}
/********************************************************************
* 名称 : write_lcd4_price(uchar hang,uchar add,uchar date)
* 功能 : 显示价格
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void write_lcd4_price(uchar hang,uchar add,uint date)
{
if(hang==1)
write_com(0x80+add); //1602写第一行的地址
else
write_com(0x80+0x40+add); //1602写第二行的地址
write_data(0x30+date/1000%10); //显示千位数
write_data(0x30+date/100%10); //显示百位数
write_data('.'); //显示小数点
write_data(0x30+date/10%10); //显示十位数
write_data(0x30+date%10); //显示个位数
}
/***********************lcd1602初始化设置************************/
void init_1602() //lcd1602初始化设置
{
write_com(0x38); //
write_com(0x0c);
write_com(0x06);
write_string(1,0," W:0.000kg "); //初始化1602显示
write_string(2,0,"P:00.00 Z:00.00"); //初始化1602显示
write_zifu(2,7,0x5c); //¥
}
/*******************重量显示程序***********************/
void write_1602_yl(uchar hang,uchar add,uint date)
/*********************AD采集程序*********************/
unsigned long HX711_Read(void) //增益128
{
unsigned long count;
unsigned char i;
hx711_dout=1;
hx711_sck=0;
count=0;
for(i=0;i<24;i++)
{
hx711_sck=1;
count=count<<1;
hx711_sck=0;
if(hx711_dout)
count++;
}
hx711_sck=1;
count=count^0x800000;//第25个脉冲下降沿来时,转换数据
hx711_sck=0;
return(count);
}
void get_pizhong() //获取皮重,秤盘重量
{
Weight_Maopi = HX711_Read();
}
void get_weight() //获取被测物体重量
{
weight = HX711_Read();
weight = weight - Weight_Maopi; //获取净重
if(weight > 0)
{
weight = (unsigned int)((float)weight/GapValue); //计算实物的实际重量
}
else
{
weight = 0;
}
}
/*****************语音报价********************/
void bojia() //语音报价
{
Send_threelines(z_price / 1000 % 10); //语音播放
Send_threelines(10);
Send_threelines(z_price / 100 % 10); //语音播放
Send_threelines(11); //点
Send_threelines(z_price / 10 % 10); //语音播放
Send_threelines(z_price % 10); //语音播放
Send_threelines(93); //元
}
/*****************语音函数********************/
void yuying() //语音函数
{
long z_p;
if(weight != 0)
if(weight == z_p) //重量稳定
{
bojia(); //语音报价
}
z_p = weight;
}
/********************独立按键程序*****************/
uchar key_can; //按键值
void key() //独立按键程序
{
static uchar key_new = 0, key_l;
key_can = 20; //按键值还原
P3 = 0x0f;
if((P3 & 0x0f) != 0x0f) //按键按下
{
delay_1ms(1); //按键消抖动
if(((P3 & 0x0f) != 0x0f) && (key_new == 1))
{ //确认是按键按下
key_new = 0;
key_l = P3 | 0xf0; //矩阵键盘扫描
P3 = key_l;
switch(P3)
{
case 0xee: key_can = 1; break; //得到按键值
case 0x77: key_can = 12; break; //得到按键值
}
beep = 0; //蜂鸣器叫一声
delay_1ms(100);
beep = 1;
}
}
else
key_new = 1;
}
/************按键控制函数*************/
void key_with()
{
if(key_can <= 9) //数字键
{
if(flag_p >= 4)
{
flag_p = 0;
}
if(flag_p == 0)
price = key_can;
else
{
price = price * 10 + key_can;
}
write_lcd4_price(2,2,price); //显示单价
flag_p ++;
}
if(key_can == 15) //删除键
{
if(price != 0 )
{
flag_p --;
price /= 10; //删除
write_lcd4_price(2,2,price);//显示单价
}
}
if(key_can == 14) //去皮
{
get_pizhong(); //获取皮重,秤盘重量
}
if(key_can == 13) //价格清零
{
flag_p = 0;
price = 0;
write_lcd4_price(2,2,price);//显示单价
}
}
/*****************主函数********************/
void main()
{
beep = 0; //蜂鸣器叫一声
delay_1ms(100);
P0 = P1 = P2 = P3 = 0xff; //单片机IO口初始化为1
init_1602(); //lcd1602初始化
get_pizhong(); //获取皮重,秤盘重量
while(1)
{
key(); //独立按键程序
if(key_can < 20)
key_with();
flag_300ms++;
if(flag_300ms >= 300) //300毫秒执行一次里面的程序
{
flag_300ms = 0;
get_weight(); //获取被测物体重量
if(weight >= 0 )
write_1602_yl(1,5,weight); //显示重量
z_price = weight * price / 1000; //总价等于重量*单价
write_lcd4_price(2,11,z_price); //显示总价
if(weight >= 5000) //超重报警
beep = ~beep; //蜂鸣器报警
else
beep = 1;
yuying(); //语音函数
}
delay_1ms(1);
}
}
复制代码
程序+原理图+PCB 51hei附件下载:
电子秤.7z
(505.64 KB, 下载次数: 61)
2024-3-6 23:09 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
19128
时间:
2024-5-10 10:59
这个pcb不太对啊
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1