51单片机设计多功能电子秤(实训项目)

news/2024/11/22 22:35:31/

一.硬件准备

1.压力传感器(HX711称重模块)

2.接线说明

如上图接线所示:称重模块HX711模块各个引脚与单片机引脚对应如下:

(1).VCC——>VCC

(2).GND——>GND

(3).SCLK——>SDA

(4).DT——>SCLK

注:引脚一定要对应接好,尤其是数据(SDA)脚和时钟(SCLK)脚

二.原理图

(一).称重模块原理图

(二).单片机原理图

三.代码详解及功能演示

(一).LCD_1602显示重量

1.子代码详解(HX711获取AD值)

/*获取ad值*/
unsigned long HX711_Read(void)
{unsigned long count; unsigned char i; HX711_DOUT = 1; _nop_();_nop_();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个脉冲下降沿来时,转换数据_nop_();_nop_();HX711_SCK = 0;  return(count);
}/*称毛皮重*/
void Get_Maopi()
{Weight_Maopi = HX711_Read();
//    Weight_Maopi = (unsigned int)((float)Weight_Maopi/423.15); 
}/*称实物重*/
void Get_Weight()
{Weight_Shiwu = HX711_Read();  Weight_Shiwu = Weight_Shiwu - Weight_Maopi;Weight_Shiwu = (unsigned int)((float)Weight_Shiwu/429.5);    
}

2.按键控制

/*按键扫描*/
void Keyscan()
{if(key1 == 0)Delay(10);if(key1 == 0){Get_Maopi();while(!key1);}if(key2 == 0)Delay(10);if(key2 == 0){Weight_Maopi = 0;while(!key2);}
}

3.源代码

#include<reg52.h>
#include <intrins.h>/*I/O口声明*/
sbit LCD1602_RS = P3^5;
sbit LCD1602_RW = P3^6;
sbit LCD1602_EN = P3^4;
sbit HX711_DOUT = P2^1; 
sbit HX711_SCK = P2^0;
sbit key1 = P3^0;
sbit key2 = P3^1;/*全局变量定义*/
unsigned long Weight_Shiwu = 0;
unsigned long Weight_Maopi = 0;/*函数声明*/
void Delay(unsigned int n);
void Init_LCD1602();//LCD1602初始化函数
void LCD1602_write_com(unsigned char com);    //写指令
void LCD1602_write_word(unsigned char *s);    //写字符串
void LCD1602_write_data(unsigned char dat);    //写数据
unsigned long HX711_Read(void);
void Keyscan();
void Get_Maopi();
void Get_Weight();int main()
{ Init_LCD1602();        //LCD1602初始化LCD1602_write_com(0x80);        //移动光标到第一行首位LCD1602_write_word(" Dian Zi Cheng! ");        //显示 Dian Zi Cheng! LCD1602_write_com(0x80 + 0x40);            //移动光标到第二行首位LCD1602_write_word("Weight :"),            //显示Weight :Delay(1000);        //1s延时while(1){Keyscan();Get_Weight();    LCD1602_write_com(0x80+0x49);        //移动光标到第二行第九位LCD1602_write_data(Weight_Shiwu%10000/1000 + 0X30);        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_word(" g");}return 0;
}/*称实物重*/
void Get_Weight()
{Weight_Shiwu = HX711_Read();  Weight_Shiwu = Weight_Shiwu - Weight_Maopi;Weight_Shiwu = (unsigned int)((float)Weight_Shiwu/429.5);    
}/*延时子函数*/
void Delay(unsigned int n)
{int i, j;for(i=0; i<n; i++)for(j=0; j<110; j++);
}//判断液晶忙,如果忙则等待
void Read_Busy()
{unsigned char busy;P0 = 0xff;LCD1602_RS = 0;LCD1602_RW = 1;do     //此语句先执行后判断{LCD1602_EN = 1;busy = P0;LCD1602_EN = 0;     //不使用时将EN拉低释放,以便于下次写数据的时候直接将EN置高}while(busy & 0x80);//判断P0的最高位是否为1,为1时忙碌(禁止),为0时不忙(允许发数据)//直到不忙时才跳出循环
}/*写指令*/
void LCD1602_write_com(unsigned char com)
{Read_Busy();//判断忙否LCD1602_RS = 0;Delay(10);LCD1602_RW = 0;    P0 = com;LCD1602_EN = 1;Delay(10);LCD1602_EN = 0;
}/*写数据*/
void LCD1602_write_data(unsigned char dat)
{Read_Busy();LCD1602_RS = 1;Delay(10);LCD1602_RW = 0;    P0 = dat;LCD1602_EN = 1;Delay(10);LCD1602_EN = 0;
}/*写连续字符(字符串)*/
void LCD1602_write_word(unsigned char *s)
{while(*s != '\0'){LCD1602_write_data(*s);s++;}
}/*初始化LCD1602*/
void Init_LCD1602()
{LCD1602_EN = 0;//LCD1602_RW = 0;LCD1602_write_com(0x38);LCD1602_write_com(0x0c);LCD1602_write_com(0x06);LCD1602_write_com(0x01);
}/*获取ad值*/
unsigned long HX711_Read(void)
{unsigned long count; unsigned char i; HX711_DOUT = 1; _nop_();_nop_();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个脉冲下降沿来时,转换数据_nop_();_nop_();HX711_SCK = 0;  return(count);
}/*称毛皮重*/
void Get_Maopi()
{Weight_Maopi = HX711_Read();
//    Weight_Maopi = (unsigned int)((float)Weight_Maopi/423.15); 
}/*按键扫描*/
void Keyscan()
{if(key1 == 0)Delay(10);if(key1 == 0){Get_Maopi();while(!key1);}if(key2 == 0)Delay(10);if(key2 == 0){Weight_Maopi = 0;while(!key2);}
}

4.功能演示

(二).LCD_1602显示重量及计算价钱(单价可以按键调节)

源代码如下

#include<reg52.h>
#include <intrins.h>/*I/O口声明*/
sbit LCD1602_RS = P3^5;
sbit LCD1602_RW = P3^6;
sbit LCD1602_EN = P3^4;
sbit HX711_DOUT = P2^1; 
sbit HX711_SCK = P2^0;
sbit key1 = P3^0;
sbit key2 = P3^1;
sbit key3 = P3^2;
sbit key4 = P3^3;
sbit Flag_ERROR = P2^3;/*全局变量定义*/
unsigned long Weight_Shiwu = 0;
unsigned long Weight_Maopi = 0;
unsigned int price = 1;
unsigned long all = 0;
/*函数声明*/
void Delay(unsigned int n);
void Init_LCD1602();//LCD1602初始化函数
void LCD1602_write_com(unsigned char com);    //写指令
void LCD1602_write_word(unsigned char *s);    //写字符串
void LCD1602_write_data(unsigned char dat);    //写数据
unsigned long HX711_Read(void);
void Keyscan();
void Get_Maopi();
void Get_Weight();
void All_Price();
int main()
{ Init_LCD1602();        //LCD1602初始化LCD1602_write_com(0x80);//移动光标到第一行首位LCD1602_write_word(" Dian Zi Cheng! ");    //显示 Dian Zi Cheng! LCD1602_write_com(0x80 + 0x40);            //移动光标到第二行首位LCD1602_write_word(" Welcom to use! ");    //显示Welcom to use!Delay(1000);        //1s延时LCD1602_write_com(0x01); //清屏LCD1602_write_com(0x80);//移动光标到第一行首位LCD1602_write_word("Weight :");//显示Weight :LCD1602_write_com(0x80 + 0x40);//移动光标到第二行首位LCD1602_write_word("p:");//显示price ://Delay(1000);        //1s延时while(1){Keyscan();Get_Weight();All_Price();if(Weight_Shiwu > 5000)        //超重报警{Flag_ERROR = 0;      //报警LCD1602_write_com(0x80+0x09);LCD1602_write_word("ERROR!");    }else{Flag_ERROR = 1;//关闭蜂鸣器        LCD1602_write_com(0x80+0x09);//移动光标到第1行第九位LCD1602_write_data(Weight_Shiwu%10000/1000 + 0X30);        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_word(" g");LCD1602_write_com(0x80+0x43);        //移动光标到第二行第3位LCD1602_write_data(price/10 + 0X30);LCD1602_write_data(price%10 + 0X30);LCD1602_write_word("Y");LCD1602_write_com(0x80+0x47);        //移动光标到第二行第7位LCD1602_write_word("All:");//显示All_price :LCD1602_write_data(all%1000/100 + 0X30);LCD1602_write_data(all%100/10 + 0X30);LCD1602_write_data(all%10 + 0X30);LCD1602_write_word("Y");        }}return 0;
}//计算价钱
void All_Price()
{    all = price *Weight_Shiwu; 
}/*称实物重*/
void Get_Weight()
{Weight_Shiwu = HX711_Read();  Weight_Shiwu = Weight_Shiwu - Weight_Maopi;Weight_Shiwu = (unsigned int)((float)Weight_Shiwu/429.5);}/*延时子函数*/
void Delay(unsigned int n)
{int i, j;for(i=0; i<n; i++)for(j=0; j<114; j++);
}//判断液晶忙,如果忙则等待
void Read_Busy()
{unsigned char busy;P0 = 0xff;LCD1602_RS = 0;LCD1602_RW = 1;do     //此语句先执行后判断{LCD1602_EN = 1;busy = P0;LCD1602_EN = 0;     //不使用时将EN拉低释放,以便于下次写数据的时候直接将EN置高}while(busy & 0x80);//判断P0的最高位是否为1,为1时忙碌(禁止),为0时不忙(允许发数据)//直到不忙时才跳出循环
}/*写指令*/
void LCD1602_write_com(unsigned char com)
{Read_Busy();//判断忙否LCD1602_RS = 0;Delay(10);LCD1602_RW = 0;    P0 = com;LCD1602_EN = 1;Delay(10);LCD1602_EN = 0;
}/*写数据*/
void LCD1602_write_data(unsigned char dat)
{Read_Busy();LCD1602_RS = 1;Delay(10);LCD1602_RW = 0;    P0 = dat;LCD1602_EN = 1;Delay(10);LCD1602_EN = 0;
}/*写连续字符(字符串)*/
void LCD1602_write_word(unsigned char *s)
{while(*s != '\0'){LCD1602_write_data(*s);s++;}
}/*初始化LCD1602*/
void Init_LCD1602()
{LCD1602_EN = 0;//LCD1602_RW = 0;LCD1602_write_com(0x38);//显示模式设置LCD1602_write_com(0x0c);//显示开及光标设置LCD1602_write_com(0x06);//显示光标移动设置LCD1602_write_com(0x01);//显示清屏
}/*获取ad值*/
unsigned long HX711_Read(void)
{unsigned long count; unsigned char i; HX711_DOUT = 1; _nop_();_nop_();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个脉冲下降沿来时,转换数据_nop_();_nop_();HX711_SCK = 0;  return(count);
}/*称毛皮重*/
void Get_Maopi()
{Weight_Maopi = HX711_Read();
//    Weight_Maopi = (unsigned int)((float)Weight_Maopi/423.15); 
}/*按键扫描*/
void Keyscan()
{if(key1 == 0){Delay(5);if(key1 == 0){while(!key1);Get_Maopi();            }}if(key2 == 0){Delay(5);if(key2 == 0){while(!key2);Weight_Maopi = 0;        }}if(key3 == 0){Delay(5);if(key3 == 0){price++;while(!key3);}}if(key4 == 0){Delay(5);if(key4 == 0){price--;while(!key4);}}
}

功能演示

四.多功能电子秤显示日历时间及闹钟设置

注:此内容详见专栏“51单片机”中《万年历》代码详解

最后,希望我的分享对你有所启发,敬请关注,持续更新,共同进步!


http://www.ppmy.cn/news/189697.html

相关文章

智能家居:步进电机驱动TB67H450FNG

直流有刷电机驱动IC&#xff1a;TB67H450FNG电机驱动器 近几年由于科技的进步和网络的普及&#xff0c;智能家居产业得到快速发展&#xff0c;智能家居产品给人们的生活品质带来显著提高&#xff0c;现代人也越来越依赖于只能家居。 在追求产品功能的同时&#xff0c;人们也越…

【STM32】步进电机及其驱动(ULN2003驱动28BYJ-48丨按键控制电机旋转)

本篇文章包含的内容 一、步进电机的结构和工作原理1.1 步进控制系统的组成1.2 步进电机简介1.3 步进电机的分类1.4 步进电机的工作原理1.4.1 单极性步进电机&#xff08;5线4相&#xff09;1.4.2 双极性步进电机&#xff08;4线2相&#xff09;1.4.3 细分器驱动原理 1.5 步进电…

面试流程:小天才步步高

春招笔试&#xff1a; 单选&#xff1a;html内联 css选择器 vue的绑定事件 vue生命周期 vue的父子传值 多选&#xff1a;数据结构 的队和栈特点&#xff0c;很简单。 简答&#xff1a; osi七层模型和tcp/ip四层模型 浏览器url发生的过程 前端优化的常用方法 编程题&#xff…

步步高笔试

步步高 若有说明&#xff1a;int n2,*p&n,*qp;则以下非法的赋值语句是&#xff1a; A pq; B *p*q; C n*q; D pn; 答案&#xff1a; D 在下列说法中&#xff0c;哪个是错误的&#xff08; &#xff09; A若进程A和进程B在临界段上互斥&#xff0c;那么当进程A处于该临界段…

28BYJ-48步进电机的控制笔记

目录 1. 概述 2. 硬件设计 3. 软件设计 1. 概述 步进电机的主要特性&#xff1a; 步进电机必须驱动才可以运转&#xff0c;驱动信号必须为脉冲信号&#xff0c;无脉冲电机静止&#xff0c;若加入适当的脉冲信号&#xff0c;则会以一定的角度&#xff08;称为步角&#xff0…

(2.54mm)TSM-120-04-S-DV-P-TR方形接线柱针脚、ADRF5545ABCPZN(通用)射频前端 SPDT

TSM-120-04-S-DV-P-TR (2.54mm) 表面安装.025"方形接线柱针脚是板对板连接器&#xff0c;有单排、双排或三排方形接线柱端子可供选择&#xff0c;带直通、直角或混合技术引脚。这些高度可靠的坚固针脚有垂直和水平两种方向&#xff0c;在混合气流 (MFG) 环境中可使用10年。…

线段树算法(C++/C)

目录​​​​​​​ 一、线段树算法的概念 二、为什么需要线段树 三、线段树算法的实现 &#xff08;1&#xff09;建树 &#xff08;2&#xff09;查询 &#xff08;3&#xff09;修改 &#xff08;4&#xff09;综合代码&#xff0c;求区间和 &#xff08;5&#xff…

Api-免费新闻资讯接口

接口简介&#xff1a; 该新闻资讯接口数据来源均来自互联网&#xff0c;您在使用接口数据时产生的版权责任我们不承担责任。 子接口&#xff1a; 获取新闻 新闻频道获取 接口地址&#xff1a;www.idmayi.com(支持:http/https) 返回格式&#xff1a; json,xml 请求方式&#xff…