基于51单片机电子称设计
(仿真+程序)
功能介绍
具体功能:
1.矩阵键盘组成按键,输入价格结算、打印;
2.用滑动变阻器和ADC0832模拟称重;
3.LCD1602可以显示重量、单价和总价;
4.接串口可以打印信息;
演示视频:
基于51单片机电子称—串口显示
添加图片注释,不超过 140 字(可选)
程序
/****
智能电子称系统设计
第一行显示: weigh: Kg
第二行显示: Price:
按下结算按键:可以计算总价
总价:
Sum:
**********************************************/
#include<reg52.h>
#include "lcd.h"
#include"weigh.h"
#define uchar unsigned char
#define uint unsigned int
uint TIM=0;
uchar dis[10],mydata[6];
uchar open=0;
sbit beep=P2^0;
extern unsigned long wei_true;
unsigned long all_in=0,sum;
unsigned char point=0,dis_n=0;
unsigned char end=0;
extern unsigned char wei_h[5];
unsigned char alarm_en=0;
unsigned char down_n,sum_all[6],sum_n=0,sen1[6];
struct key
{
uchar down; //输入次数
}key={0};
unsigned char code KEYTAB[16] ={0x7e,0xBE,0XBD,0xBB,0xDE,0xDD,0xDB,0xEE,0xED,0xEB,0x7D,0x7B,0x77,0xb7,0xd7,0xe7};
void clear_all();//
/*******************************************
*函数名称:delay(uint t)延时函数
*函数作用:延时1ms左右
*
*********************************************/
void delay(uint t)
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<110;j++);
}
void sen(unsigned char r_byte)
{
SBUF = r_byte;
while( TI == 0 ); //查询法
TI = 0;
}
void send_print1()
{
unsigned char i=0;
sen('W');
sen('e');
sen('i');
sen('g');
sen('h');
sen(':');
sen(wei_h[0]+48);
sen(wei_h[1]+48);
sen(wei_h[2]+48);
sen(wei_h[3]+48);
sen(' ');
sen('P');
sen('r');
sen('i');
sen('c');
sen('e');
sen(':');
for(i=0;i<down_n;i++)
{
sen(sen1[i]);
}
sen('S');
sen('u');
sen('m');
sen(':');
for(i=0;i<sum_n;i++)
{
sen(sum_all[sum_n-i-1]);
}
}
/*******************************************
*函数名称:keyscan( ) 键盘扫描函数
*函数作用: 1、扫描键盘,获得键值
2、显示输入键值(*号),并保存
3、读取功能按键,并执行相应的功能
按键的功能划分如下:
| 7 | 8 | 9 | clear |
---------------------------------------
| 4 | 5 | 6 | 键 |
---------------------------------------
| 1 | 2 | 3 | 没有使用 |
---------------------------------------
| |point| |
| 0 | | | 没有使用 |
---------------------------------------
*********************************************/
unsigned char keyscan(void)
{
unsigned char i=0,j,t;
unsigned char s=0,init_n;
unsigned char point_wei=0;
unsigned char redat;
unsigned char keynum=0;
P3=0XFF;
P1=0XF0;
redat=P3&0XF0;
if(redat!=0xF0)
{
delay(12);
redat=P3&0XF0;//再次延时检测
if(redat!=0xF0)
{
keynum=redat;//获得第四位
P1=0XFF;//看来这个地方是必须的
P3=0X0F;//开始读取高四位
delay(1);
redat=P1&0X0F;
keynum|=redat;
for(i=0;i<16;i++)
{
if(keynum==KEYTAB[i])
{
//这个地方发送出去
if(i<10)
{
sen1[down_n]=i+48;
down_n++;
}
else if(i==10)
{
sen1[down_n]='.';
down_n++;
}
if(i<10) //如果输入键值小于10即0-9
{
if(key.down==1)
{
if(mydata[0]>0)
{
//这个时候才读取新的数据,否则等待按下小数点
mydata[key.down]=i; // 保存按键
lcd_pos(key.down+70); //
lcd_wdat(i+48);
key.down++; //按键次数加1
}
}
else
{
if(point==0)
{
mydata[key.down]=i; // 保存按键
}
else
{
mydata[key.down-1]=i;
}
mydata[key.down]=i; // 保存按键
lcd_pos(key.down+70); //
lcd_wdat(i+48);
key.down++; //按键次数加1
}
}
else if(i==10)
{
if(key.down>0)
{
if(point==0) //一次运行过程中,只能输入一个小数点
{
lcd_pos(key.down+70); //
lcd_wdat('.');
key.down++; //按键次数加1
point=key.down;//保存当前出现位置
} //记录小数点出现的位置
}
}
else if(i==11)
{
end=1;
//结算 //得到实际值
//先不讨论小数点的问题,最后在分析小数点问题
sum=0;
if(point>0) key.down=key.down-1;
for(j=0;j<key.down;j++)
{
//计算单价
sum=sum*10+mydata[j];//
}
all_in=wei_true*sum; //把这个数据显示出来的
lcd_wcmd(0x01);// 清除屏幕
lcd_pos(0);
lcd_wdat('S');
lcd_pos(1);
lcd_wdat('u');
lcd_pos(2);
lcd_wdat('m');
lcd_pos(3);
lcd_wdat(':');
for(j=0;j<10;j++)
{
dis[j]=all_in%10;
all_in=all_in/10;
if(all_in==0)
{
dis_n=j;
break;
}
}
if(point==0)
{
point_wei=0;
}
else
{
point_wei=key.down-point+1;
}
//这个地方出现了问题了
sum_n=dis_n;
for(j=0;j<=dis_n;j++)
{
if(j==0) sum_n=0;
if((j==point_wei)&&(point_wei>0))
{
lcd_pos(15-j);
lcd_wdat('.');
sum_all[sum_n]='.';
sum_n++;
s=1;
lcd_pos(15-(j+s));
lcd_wdat(dis[j]+48);
sum_all[sum_n]=dis[j]+48;
sum_n++;
}
else
{
lcd_pos(15-(j+s));
lcd_wdat(dis[j]+48);
sum_all[sum_n]=dis[j]+48;
sum_n++;
}
}
}
else if(i==15)
{
//保存
clear_all();
down_n=0;//清除0
for(t=0;t<6;t++)
{
mydata[t]=0;
}
key.down=0;
end=0;
point=0;
}
else if(i==14)
{
send_print1();
sum_n=0;
}
/*****如果按下清除键******/
delay(900);//键盘延时
}
}
}
}
return 0;
}
/*******************************************
*函数名称:init_timer( ) 定时器初始化函数
*函数作用:
定时器定时时间1ms
*********************************************/
void init_timer() //
{
SCON = 0x50; //REN=1允许串行接受状态,串口工作模式2
TMOD|= 0x21;//
TH0 = 0xEC;
TL0 = 0x78;
ET0=1;
TH1 = 0xFD; //baud*2 /* reload value 19200、数据位8、停止位1。效验位无(11.0592)
TL1 = 0xFD;
TR1 = 1; //开启定时器1
TR0 = 1; //关闭
ES = 1; //开串口中断
EA=1;
}
/*******************************************
*函数名称:clear( ) 清除函数
*函数作用:
只清除按下的次数,以及初始化字符显示
*********************************************/
void clear() reentrant
{
key.down=0;
init_char();
}
/*******************************************
*函数名称:clear_all( ) 清除所有的标志变量
*函数作用
*********************************************/
void clear_all() //所有的变量清零
{
clear();
}
void sys_init()
{
lcd_init();
init_char();
init_timer();
}
/*******************************************
*函数名称:main( ) 主函数
*函数作用:
这个函数必须有的
*********************************************/
void main()//
{
beep=1;
sys_init();
while(1)
{
keyscan();
if(!end)
{
get_wei();
if(alarm_en)
{
beep=0;
}
else
{
beep=1;
}
}
delay(700);
}
}
/*******************************************
*函数名称:TI_int1( ) 定时器1中断处理函数
*函数作用:
*********************************************/
void T0_int1(void) interrupt 1//定时器中断
{
TH0 = (65536-10000)/256;
TL0 = (65536-10000)%256;
TIM++;
if(TIM>100)
{
TIM=0;
open=1;
}
}
硬件设计
使用元器件:
单片机:AT89C52;
(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)
添加图片注释,不超过 140 字(可选)
设计资料
01仿真图
本设计使用proteus7.8和proteus8.9两个版本设计!具体如图!
添加图片注释,不超过 140 字(可选)
02程序
本设计使用软件keil5版本编程设计!具体如图!
添加图片注释,不超过 140 字(可选)
03设计资料
资料获取请关注同名公众号,全部资料包括程序(含注释)、仿真源文件等。具体内容如下,全网最全!!
可以关注下方公众号!
点赞分享一起学习成长。