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

发布于:2025-09-03 ⋅ 阅读:(13) ⋅ 点赞:(0)

 目录

一、主要功能

二、使用步骤

三、硬件资源

四、软件设计

五、实验现象

一、主要功能

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

五、实验现象

演示视频:


网站公告

今日签到

点亮在社区的每一天
去签到