这是我的单片机设计,主要是使用压力传感器、HX711模块和51单片机做的,附件里包含了电子称的原理图和源代码
这个简易电子称共有三个模式:
模式1:进行普通的物体测量;
模式2:计价模式;
模式3:累计测量模式;
此外,除了可以用按键进行模式的切换,还可通过上位机发送指令进行模式的切换。
此次课程设计主要是针对51单片机的基础知识的运用,其中主要运用了以下知识点:对矩阵按键、LED灯、蜂鸣器、AD转换、LCD12864、
定时器0、定时器1、外部中断0、外部中断1、串口(使用到定时器2,所以在烧录时芯片请用STC89C52)等。
简易介绍
基于51单片机设计的简易电子称,性能比较简单,共分为3个模式,模式一是用于重物的测量,模式2主要用于物品的计价,不过单价输入只能是整数,由于重物重量精确到小数点后两位,所以单计价后的价格可以是小数的。模式三是重物的累计测量。同时处理按键进行模式切换后,还可以通过上位机发送指令进行模式切换,当上位机发送1时,接收机接到指令后启动模式1,并发送“模式1启动”。其他模式也与此相似,但当上位机发送其他字符时,单片机会返回“模式切换失败,请输入正确序号”类似的字样。
模式说明
模式1
普通测量模式,只进行普通的测量
模式2
计价测量模式,可根据输入的价格和被测物重量计算价格
模式3
累计测量模式,可在按键按下后累计被测物重量,结束键按下后显示总重量
按键说明
数字键
模式2下的价格输入键,只在模式2下有效
功能键A
按下A键进入模式1
功能键B
按下B键进入模式2
功能键C
按下C键进入模式3
功能键D
模式3下按下后被测物体重量被确认,若没按下模式3结束键,继续进行下一被测物体的测量。只在模式3下有效
功能键*
模式2下的价格清除键,按下后价格归0,显示清空。只在模式2下有效
功能键#
模式2下的价格确认键,按下后下个被固定,再按下数字键时价格处于重新输入的状态。模式3下作为模式3结束键,按下按键后显示累计测量的总重量。
界面简介模式1界面
模式2界面
模式3界面
模式3最终界面
程序主流程图
各个模块流程图(略)
单片机源程序如下:
#include "reg52.h"
#include "HX711.h"
#include "lcd12864.h"
#include "module.h"
#include "keyborad.h"
//*************************************************************************
// 定时器0初始化函数
//*************************************************************************
void timer0_init(void)//50ms
{
ET0 = 1; //允许定时器0中断
TMOD = 0x11; //定时器工作方式选择
TL0 = 0xb0;
TH0 = 0x3c; //定时器赋予初值
TR0 = 1; //启动定时器
EA = 1;
}
//*************************************************************************
// 定时器0中断服务函数
// 每秒中刷新5次
//*************************************************************************
bit weight_flag=0; //定时器0的标志位
uchar time0_count=0; //定时器0计数标志
void timer0() interrupt 1
{
TL0 = 0xb0;
TH0 = 0x3c; //定时器赋予初值
time0_count++;
if(time0_count>=4){
time0_count = 0;
weight_flag = 1;
}
}
//*************************************************************************
// 定时器1初始化函数
//*************************************************************************
void timer1_init(void) //50ms
{
ET1 = 1;
TL1 = 0xB0; //设置定时初值
TH1 = 0x3C; //设置定时初值
// TR1 = 1; //定时器1开始计时
}
//*************************************************************************
// 定时器0中断服务函数
// 计时3秒钟
//*************************************************************************
bit weight_flag1; //定时器1的标志位
uchar timer1_count;//定时器计1数标志
void timer1(void) interrupt 3
{
TL1 = 0xB0; //设置定时初值
TH1 = 0x3C; //设置定时初值
timer1_count++;
if (timer1_count == 60) {
TR1 = 0;
timer1_count = 0;
weight_flag1 = 1;
}
}
//*************************************************************************
// 外部中断0初始化
// 用来调整超重报警值
//*************************************************************************
ulong weight_alarm=200000;
void INIT0_int()
{
EX0 = 1;
IT0 = 1;
}
//*************************************************************************
// 外部中断0服务函数
//*************************************************************************
void INIT0_deal() interrupt 0
{
weight_alarm-=50000;if(weight_alarm<=100000)weight_alarm=450000;
}
//*************************************************************************
// 外部中断1初始化
// 用来调整超重报警值
//*************************************************************************
void INIT1_int()
{
EX1 = 1;
IT1 = 1;
}
//*************************************************************************
// 外部中断1服务函数
//*************************************************************************
void INIT1_deal() interrupt 2
{
weight_alarm+=50000;if(weight_alarm>=450000)weight_alarm=200000;
}
//*************************************************************************
// 串口发送数据函数
//*************************************************************************
void SendData(unsigned char *s)
{
while(*s>0)
{
SBUF = *s;
while(!TI);
TI = 0;
s++;
}
}
//*************************************************************************
// 串口初始化函数
//*************************************************************************
sfr T2MOD = 0x9C;
void USTAR_init()
{
PS = 1;
SCON = 0x50;
T2MOD = 0x01;
T2CON = 0x30;
TH2 = 0xFF;
TL2 = 0xDC;
RCAP2H = 0XFF;
RCAP2L = 0xDC; //波特率9600
TR2 = 1;
ES = 1;
EA = 1;
}
//*************************************************************************
// 串口中断服务函数
//*************************************************************************
uchar ReceiveData=0;
void USTAR() interrupt 4
{
ReceiveData = SBUF;
while(!RI);
RI = 0;
if(ReceiveData=='1')
{
SendData("模式1启动n");
}
else if(ReceiveData=='2')
{
SendData("模式2启动n");
}
else if(ReceiveData=='3')
{
SendData("模式3启动n");
}
else
{
SendData("切换失败,");
SendData("非所属模式n");
}
}
//*************************************************************************
// 串口模式切换界面函数
//*************************************************************************
void BoundaryChange()
{
if(ReceiveData==0)return;
if(ReceiveData=='1')
{
module1_flag=1;
module2_flag=0;
module3_flag=0;
ReceiveData=0;
module1_init();
}
else if(ReceiveData=='2')
{
module1_flag=0;
module2_flag=1;
module3_flag=0;
ReceiveData=0;
module2_init();
}
else if(ReceiveData=='3')
{
module1_flag=0;
module2_flag=0;
module3_flag=1;
ReceiveData=0;
module3_init();
}
}
//*************************************************************************
// 报警函数
//*************************************************************************
sbit beep = P2^7;
sbit led = P0^0;
void beep_alarm()
{
uint i=500;
while(i--){
beep = ~beep;
if(i==1)led =~led;
delay(1);}
}
//*************************************************************************
// 主函数
//*************************************************************************
void main()
{
lcd_init(); //LCD12864初始化
USTAR_init(); //串口中断初始化
timer0_init(); //定时器0初始化
timer1_init(); //定时器1初始化
INIT0_int(); //外部中断0初始化
INIT1_int(); //外部中断1初始化
Get_MaoPi();
Get_MaoPi();
delay(1000);
Get_MaoPi();
Get_MaoPi(); //获取毛皮重量
while(1)
{
BoundaryChange();
if(weight_flag==1){
Get_Weight();
weight_flag=0;} //每次标志位为1的时候刷新
Key_Deal();
if(module1_flag==1) module1();
else if(module2_flag==1)module2();
else if(module3_flag==1)module3();
if(weight >= weight_alarm){beep_alarm();}else{led=1;}//超重报警
if(module3_flag != 1){thing_count=1;Totle_weight=0;}//非模式3下的计数量全部清零
}
}
上一篇:基于51单片机PWM调速数码管显示测速
下一篇:单片机+PCF8591实现数字电压表
推荐阅读最新更新时间:2024-11-02 12:20