目录
一、主要功能
1、LCD1602显示重量、单价和总价
3、未称重显示当前时间
3、矩阵键盘组成按键,输入
4、可以去皮,校准,称重范围为0~10Kg
5、超重报警
二、使用步骤
基于51单片机的智能电子秤设计是一种结合传感器技术、模数转换和嵌入式系统的典型应用,其显示LCD1602显示和矩阵按键,称重模块组成。
三、硬件资源
1、51单片机核心模块
2、按键模块
3、DS1302传感器、HX711传感器
4、蜂鸣器模块
5、指示灯
6、LCD1602显示模块
四、软件设计
#include <reg52.h>
#include <intrins.h>
#include <string.h>
int bdata flag_key;
#include "main.h"
#include "LCD1602.h"
#include "HX711.h"
#include "keyboard.h"
#include "eeprom52.h"
#include "wannianli.h"
#include "yyxp.h"
#define uchar unsigned char
#define uint unsigned int
unsigned long HX711_Buffer = 0;
unsigned long Weight_Maopi = 0;
unsigned long Weight_Maopi_0 = 0;
int qupi=0;
long Weight_Shiwu = 0;
int Weight_beep = 5000;
//键盘处理变量
unsigned char keycode;
unsigned char DotPos; //小数点标志及位置
extern unsigned int T2beep;
uint GapValue,GapValue1;
unsigned long idata price; //单价,长整型值,单位为分
unsigned long idata danjia[8]={11,22,33,44,100,200,300,400};
unsigned char count_danjia;
unsigned long idata money,total_money; //总价,长整型值,单位为分
//定义标识
volatile bit FlagTest = 0; //定时测试标志,每0.5秒置位,测完清0
volatile bit FlagKeyPress = 0; //有键按下标志,处理完毕清0
//校准参数
//因为不同的传感器特性曲线不是很一致,因此,每一个传感器需要矫正这里这个参数才能使测量值很准确。
//当发现测试出来的重量偏大时,增加该数值。
//如果测试出来的重量偏小时,减小改数值。
//该值可以为小数
//#define GapValue 349
sbit LED=P3^6;
sbit K1 = P3^0; //计算总价并语言播报
//sbit K3 = P2^3;
volatile bit ClearWeighFlag = 0; //传感器调零标志位,清除0漂
/******************把数据保存到单片机内部eeprom中******************/
void write_eeprom()
{
SectorErase(0x2000);
GapValue1=GapValue&0x00ff;
byte_write(0x2000, GapValue1);
GapValue1=(GapValue&0xff00)>>8;
byte_write(0x2001, GapValue1);
byte_write(0x2060, a_a);
}
/******************把数据从单片机内部eeprom中读出来*****************/
void read_eeprom()
{
GapValue = byte_read(0x2001);
GapValue = (GapValue<<8)|byte_read(0x2000);
a_a = byte_read(0x2060);
}
/**************开机自检eeprom初始化*****************/
void init_eeprom()
{
read_eeprom(); //先读
if(a_a != 1) //新的单片机初始单片机内问eeprom
{
GapValue = 1000;
a_a = 1;
write_eeprom(); //保存数据
}
}
//显示单价,单位为元,四位整数,两位小数
void Display_Price()
{ LCD1602_write_com(0x89);
LCD1602_write_word("PR:");
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(0x80);
LCD1602_write_word("WE");
LCD1602_write_com(0x82);
LCD1602_write_data(' ');
LCD1602_write_data(Weight_Shiwu%10000/1000 + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(Weight_Shiwu%1000/100 + 0x30);
LCD1602_write_data(Weight_Shiwu%100/10 + 0x30);
LCD1602_write_data(Weight_Shiwu%10 + 0x30);
LCD1602_write_data(' ');
}
//显示总价,单位为元,四位整数,两位小数
void Display_Money()
{
// unsigned int i,j;
LCD1602_write_com(0x80+0x40); //指针设置
LCD1602_write_word("S:");
LCD1602_write_com(0xc9);
LCD1602_write_word("T:");
LCD1602_write_com(0xc7);
LCD1602_write_word(" ");
if (money>9999) //超出显示量程
{
LCD1602_write_com(0x80+0x40+2);
LCD1602_write_word("---.-");
return;
}
if (money>=1000)
{
LCD1602_write_com(0x80+0x40+2);
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+2);
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+2);
LCD1602_write_data(0x20);
LCD1602_write_com(0x80+0x40+3);
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+2);
LCD1602_write_data(0x20);
LCD1602_write_com(0x80+0x40+3);
LCD1602_write_data(0x20);
LCD1602_write_com(0x80+0x40+4);
LCD1602_write_data(0 + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(money%10 + 0x30);
}
if (total_money>9999) //超出显示量程
{
LCD1602_write_com(0x80+0x40+11);
LCD1602_write_word("---.-");
return;
}
if (total_money>=1000)
{
LCD1602_write_com(0x80+0x40+11);
LCD1602_write_data(total_money/1000 + 0x30);
LCD1602_write_data(total_money%1000/100 + 0x30);
LCD1602_write_data(total_money%100/10 + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(total_money%10 + 0x30);
}
else if (total_money>=100)
{
LCD1602_write_com(0x80+0x40+11);
LCD1602_write_data(0x20);
LCD1602_write_data(total_money%1000/100 + 0x30);
LCD1602_write_data(total_money%100/10 + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(total_money%10 + 0x30);
}
else if(total_money>=10)
{
LCD1602_write_com(0x80+0x40+11);
LCD1602_write_data(0x20);
LCD1602_write_com(0x80+0x40+12);
LCD1602_write_data(0x20);
LCD1602_write_data(total_money%100/10 + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(total_money%10+ 0x30);
}
else
{
LCD1602_write_com(0x80+0x40+11);
LCD1602_write_data(0x20);
LCD1602_write_com(0x80+0x40+12);
LCD1602_write_data(0x20);
LCD1602_write_com(0x80+0x40+13);
LCD1602_write_data(0 + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(total_money%10 + 0x30);
}
}
//按键响应程序,参数是键值
//返回键值:
// 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: //清零键
speak(41);
if(qupi==0)
qupi=Weight_Shiwu;
else
qupi=0;
Display_Price();
// FlagSetPrice = 0;
DotPos = 0;
break;
case 11: //删除键,按一次删除最右一个数字
price=0;
DotPos=0;
Display_Price();
break;
case 12: //加
if(GapValue<10000)
GapValue++;
break;
case 13: //减
if(GapValue>1)
GapValue--;
break;
case 14: count_danjia++;
if(count_danjia>7)
count_danjia=0;
price = danjia[count_danjia];
Display_Price();
break;
case 15: //小数点按下
DotPos = 1; //小数点后第一位
break;
}
}
//****************************************************
//主函数
//****************************************************
void main()
{
yyxp_rest=1;
yyxp_data=1;
init_eeprom(); //开始初始化保存的数据
Init_LCD1602(); //初始化LCD1602
EA = 0;
Data_Init();
Timer0_Init();
//初中始化完成,开断
EA = 1;
// Ds1302Init();
// Get_Maopi();
LCD1602_write_com(0x80); //指针设置
LCD1602_write_word(" Welcome To Use "); //
LCD1602_write_com(0x80+0x40); //指针设置
LCD1602_write_word("Electronic Scale");
Delay_ms(2000);
Get_Maopi();
LCD1602_write_com(0x80); //指针设置
LCD1602_write_word("WE:0.000 PR:00.0");
LCD1602_write_com(0x80+0x40); //指针设置
LCD1602_write_word("S: 0.0 T: 0.0");
Display_Price();
// Get_Maopi(); //称毛皮重量
// Weight_Shiwu = 9000;
while(1)
{
keyscan();
if (K1== 0 && T2beep==1)
{
T2beep=0;
}
if (FlagTest==1&&keynum==0)
{
Get_Weight();
}
if(T2beep==0)
{
if(Weight_Shiwu<10)
{
if(keynum==0)
display();
if(key2==0)
{
Delay_ms(5);
if(key2==0)
{
speak(41);
if(qupi==0)
qupi=Weight_Shiwu;
else
qupi=0;
while(key2==0);
}
}
}
else
{
keycode = Getkeyboard();
if(K1==0)
{
Delay_ms(5);
if(K1==0)
{
total_money += money;
Display_Money();
bofang(1,total_money);
while(K1==0);
}
}
if(key1==0)
{
Delay_ms(5);
if(key1==0)
{
total_money = 0;
Display_Money();
bofang(1,total_money);
while(key1==0);
}
}
if(key3==0)
{
Delay_ms(5);
if(key3==0)
{
total_money = 0;
Display_Money();
bofang(2,price);
bofang_zhongliang(Weight_Shiwu);
bofang(1,money);
while(key3==0);
}
}
}
}
//有效键值0-15
if (keycode<16)
{
KeyPress(keycode);
// Buzzer=0;
Delay_ms(100);
// Buzzer=1;
while(keycode<16)
{
if(keycode==12||keycode==13)
{
// Buzzer=0;
Delay_ms(10);
// Buzzer=1;
KeyPress(keycode);
// Get_Weight();
flag_key=1;
}
keycode = Getkeyboard();
}
write_eeprom(); //保存数据
}
}
}
//****************************************************
//称重
//****************************************************
void Get_Weight()
{
Weight_Shiwu = HX711_Read();
Weight_Shiwu = Weight_Shiwu - Weight_Maopi;
if((int)((float)Weight_Shiwu*10/GapValue)>qupi)
Weight_Shiwu = (int)((float)Weight_Shiwu*10/GapValue)-qupi; //计算实物的实际重量
else
Weight_Shiwu = 0;
// Weight_Shiwu = (unsigned int)((float)Weight_Shiwu)-qupi;
if(T2beep==0)
{
if(Weight_Shiwu > 10000)
{
// Buzzer = !Buzzer;
LED=!LED;
if(yyxp_busy==1)
speak(40);
LCD1602_write_com(0x82);
LCD1602_write_word("--.---");
}
else
{
if(Weight_Shiwu<Weight_beep)
LED=0;
else if(Weight_Shiwu>Weight_beep)
{
LED=1;
speak(40);
}
// Buzzer = 1;
if(Weight_Shiwu>10)
{
Display_Weight();
money = Weight_Shiwu*price/1000; //money单位为分
//显示总金额
Display_Money(); Display_Price();
}
}
}
}
//****************************************************
//获取毛皮重量
//****************************************************
void Get_Maopi()
{
unsigned char clear;
mm: Weight_Maopi_0 = HX711_Read();
for(clear=0;clear<10;clear++)
{
// Buzzer=1;
LED=1;
Delay_ms(100);
LED=0;
Delay_ms(100);
}
Weight_Maopi = HX711_Read();
if(Weight_Maopi/GapValue!=Weight_Maopi_0/GapValue)
goto mm;
// Buzzer=0;
Delay_ms(500);
// Buzzer=1;
}
//****************************************************
//MS延时函数(12M晶振下测试)
//****************************************************
void Delay_ms(unsigned int n)
{
unsigned int i,j;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
五、实验现象
演示视频: