【51单片机】【protues仿真】 基于51单片机智能电子秤系统

目录

一、主要功能

二、使用步骤

三、硬件资源

四、软件设计

五、实验现象

一、主要功能

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;

}

//每0.5秒称重一次

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++);

}

五、实验现象

演示视频:

相关推荐
一枝小雨6 小时前
【DMA】DMA入门:理解DMA与CPU的并行
单片机·系统架构·dma·嵌入式·arm
liujing102329296 小时前
Day08_单片机-ADC和DMA
单片机·嵌入式硬件
华清远见IT开放实验室7 小时前
华清远见携STM32全矩阵产品及创新机器狗亮相2025 STM32研讨会,共启嵌入式技术探索新程
linux·人工智能·stm32·单片机·嵌入式硬件·虚拟仿真
蜀黍@猿7 小时前
【GD32】中断系统
单片机·嵌入式硬件
LeenixP8 小时前
STM32H750xx【QSPI】轮询方式读写GD25Q64E
c语言·stm32·嵌入式硬件·cubemx·stm32h7·keilmdk
小莞尔9 小时前
【51单片机】【protues仿真】基于51单片机心形流水灯系统
c语言·stm32·单片机·嵌入式硬件·51单片机
沐欣工作室_lvyiyi9 小时前
基于单片机的老年人身体健康蓝牙监测手环(论文+源码)
stm32·单片机·嵌入式硬件·毕业设计·老年人监测
猫头虎10 小时前
2025最新超详细FreeRTOS入门教程:第二十四章 FreeRTOS与低功耗设计
网络·stm32·嵌入式硬件·网络协议·安全·开源·51单片机
the sun3410 小时前
模电基础:静态工作点稳定的典型电路
单片机·嵌入式硬件
强化学习与机器人控制仿真10 小时前
LeRobot 入门教程(九)使用 Android、iOS 手机控制机械臂
开发语言·人工智能·stm32·深度学习·神经网络·算法·机器人