51单片机设计多功能电子秤(实训项目)
一.硬件准备
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单片机”中《万年历》代码详解
最后,希望我的分享对你有所启发,敬请关注,持续更新,共同进步!