|
#include"reg51.h"
/****************************************************************
环宇电子秤系统 stc89C52单片机控制
12864 LCD显示 制作日期:2015/06/27
*****************************************************************/
#define uchar unsigned char
#define uint unsigned int
unsigned char jian_ma,flag,jiao_flag,set_flag;
unsigned int heavy,price=1,money,alarm=500,jiao_zhun=1010; //相关变量定义 ,上限报警值初始值为500克
unsigned char menu,jia,jian,confr,fu,menu_flag,exit;
long data_num,data_temp,data_flash;
unsigned char f=0;
unsigned char code table[]={" Welcome to you"};
unsigned char code table1[]={" Weight "};
sbit IRIN = P3^3; //红外接收器数据线
sbit ADDO=P1^0; //ad采集数据接口
sbit ADSK= P1^1; //ad采集时钟接口
sbit rs=P2^3;
sbit rw=P2^4; //液晶接口定义
sbit lcden=P2^5;
sbit bell=P3^6; //蜂鸣器定义
sbit key=P2^7; //按键定义
#define Imax 14000 //此处为晶振为12时的取值, 红外解码
#define Imin 8000 //如用其它频率的晶振时,
#define Inum1 1450 //要改变相应的取值。
#define Inum2 700
#define Inum3 3000
unsigned char Im[4]={0x00,0x00,0x00,0x00};
unsigned long m,Tc;
void delay_ms(unsigned char x) //x*0.14MS
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}
void delay(unsigned int t) //延时函数
{
uint x,y;
for(x=t;x>0;x--)
for(y=12;y>0;y--);
}
//****************************************************
/* 名称:写命令函数
功能:向LED1602中写命令
入口参数:uchar com
出口参数:无
*/
void write_com(unsigned char com)
{
rs=0;
rw=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/* 名称:写数据函数
功能:向LED1602中写数据
入口参数:uchar date
出口参数:无
*/
void write_date(unsigned char date)
{
rs=1;
rw=0;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/* 名称:初始化函数
功能:初始化LED1602
入口参数:无
出口参数:无
*/
void lcd_init()
{
unsigned char num;
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01); //清屏
write_com(0x80);
delay(5);
write_com(0x80);
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(5);
}
delay(20000);
write_com(0x80);
for(num=0;num<15;num++)
{
write_date(table1[num]);
delay(5);
}
}
void display( unsigned int weight,unsigned int bj,unsigned int vl)
{ unsigned int qian,bai,shi,ge;
qian=(weight/1000)%10;
bai=(weight/100)%10;
shi=(weight/10)%10;
ge=weight%10;
write_com(0x87); //重量显示
write_date(':');
if(fu) //为赋值则显示负号
{
fu=0;
write_date('-');
}
else
write_date(' ');
if(qian)
{
write_date(0x30+qian);
write_date(0x30+bai);
write_date(0x30+shi);
write_date(0x30+ge);
}
else
if(bai)
{
write_date(' ');
write_date(0x30+bai);
write_date(0x30+shi);
write_date(0x30+ge);
}
else
if(shi)
{
write_date(' ');
write_date(' ');
write_date(0x30+shi);
write_date(0x30+ge);
}
else
{
write_date(' ');
write_date(' ');
write_date(' ');
write_date(0x30+ge);
}
write_date('g');
qian=(bj/1000)%10;
bai=(bj/100)%10;
shi=(bj/10)%10;
ge=bj%10;
write_com(0x80+0x40); //报警值显示
write_date('M');
write_date(':');
if(qian)
{
write_date(0x30+qian);
write_date(0x30+bai);
write_date(0x30+shi);
write_date(0x30+ge);
}
else
if(bai)
{
write_date(' ');
write_date(0x30+bai);
write_date(0x30+shi);
write_date(0x30+ge);
}
else
if(shi)
{
write_date(' ');
write_date(' ');
write_date(0x30+shi);
write_date(0x30+ge);
}
else
{
write_date(' ');
write_date(' ');
write_date(' ');
write_date(0x30+ge);
}
qian=(vl/1000)%10; //校准值显示
bai=(vl/100)%10;
shi=(vl/10)%10;
ge=vl%10;
write_com(0x80+0x47);
write_date('V');
write_date(':');
if(qian)
{
write_date(0x30+qian);
write_date(0x30+bai);
write_date(0x30+shi);
write_date(0x30+ge);
}
else
if(bai)
{
write_date(' ');
write_date(0x30+bai);
write_date(0x30+shi);
write_date(0x30+ge);
}
else
if(shi)
{
write_date(' ');
write_date(' ');
write_date(0x30+shi);
write_date(0x30+ge);
}
else
{
write_date(' ');
write_date(' ');
write_date(' ');
write_date(0x30+ge);
}
if(set_flag) //报警上限光标打开
{
write_com(0x80+0x40); //报警值闪烁
write_com(0x0f); //报警值显示
write_date('M');
}
if(jiao_flag)
{
write_com(0x80+0x47);
write_com(0x0f); // 校准值闪烁
write_date('V');
}
}
void read_count() //ad采集函数
{
unsigned long count;
unsigned char i;
ADSK=0;//使能ad
count=0;
while(ADDO); //等待ad转换结束
for(i=0;i<24;i++)
{
ADSK=1; //PD_SCK置高,发送脉冲
count=count<<1;
// delayp();
ADSK=0; //pd_sck置低
if(ADDO)count++;
}
ADSK=1;
count=count^0x800000; //第25个脉冲下降沿来时,转换数据
// delayp();
ADSK=0;
data_num=count; // 读出来的数据赋值给变量data_num
}
/****************************************************************
蜂鸣器 报警
*****************************************************************/
void beep()
{
unsigned char i;
for(i=0;i<20;i++)
{
bell = 0;
delay(40);
bell = 1;
}
}
void price_change() //遥控按键扫描函数
{
jian_ma=jian_ma&0x1f;
if(jian_ma>=0x1f)
{
flag=0;
}
if(flag)
{
flag=0;
switch (jian_ma)
{
case 0x01: //按下2号按键进入 校准值设定
menu_flag=1;
jiao_flag=1;
set_flag=0;
beep();
break;
case 0x02: //按下3号按键进入 报警值设定状态
menu_flag=2;
jiao_flag=0;
set_flag=1;
beep();
break;
case 0x0c: //*键进入清零
read_count();
data_temp=data_num;
beep();
break;
case 0x11: //加键
jia=1;
beep();
break;
case 0x19: //减键
jian=1;
beep();
break;
case 0x15:
flag=0;
menu_flag=0;//按下ok按键退出
set_flag=0;
jiao_flag=0;
write_com(0x0c);
beep();
exit=1;
break;
}
}
}
void sao_miao()//按键扫描函数
{
if(key==0)
{
delay(10);
if(!key)
{
while(!key);
read_count();
delay(500);
read_count();
data_temp=data_num; //重新读取ad采集值,进入清零功能
}
}
}
void chu_li() //单价设定函数
{
price_change(); //遥控按键扫描函数
while(menu_flag) //对遥控按键的处理
{
price_change();
if(set_flag) //报警值设定
{
if(jia)
{
jia=0;
if(alarm<5000) //最大数值为5000
alarm++;
}
if(jian)
{
jian=0;
if(alarm>=2) //最小数值为1
alarm--;
}
}
if(jiao_flag) //校准值设定
{
if(jia)
{
jia=0;
if(jiao_zhun<5000) //最大数值为5000
jiao_zhun++;
}
if(jian)
{
jian=0;
if(jiao_zhun>=2) //最小数值为1
jiao_zhun--;
}
}
delay(500);
read_count();
if(data_num>=data_temp) // 比较采集出来的数值与临时变量
{
data_num=(data_num-data_temp);
heavy=(unsigned int)(data_num/jiao_zhun);//1677; //计算重量
}
delay(5000);
display(heavy,alarm,jiao_zhun);
}
sao_miao(); //按键扫描函数
}
/****************************************************************
/****************************************************************
主函数
*****************************************************************/
void main()
{
uchar i=0;
IRIN=1; //I/O口初始化
m=0;
f=0;
lcd_init();
IT1=1;
EX1=1; //开外部中断
TMOD=0x11; //定时器方式
TH0=0;
TL0=0;
TR0=1; //开定时器
EA=1; //开总中断
P0=0;
delay(50);
delay(100);
read_count(); //ad采集函数
delay(3000);
read_count(); //ad采集函数
delay(3000);
read_count(); //ad采集函数
data_temp=data_num; //采集数据赋值给临时变量 data_temp
while(1)
{
read_count();
if(data_num>=data_temp) // 比较采集出来的数值与临时变量
data_num=(data_num-data_temp);
else
{
data_num=(data_temp-data_num);
if(data_num>=500)
{
fu=1;
}
else
{
fu=0;
data_num=0;
}
}
heavy=(unsigned int)(data_num/jiao_zhun);//1677; //计算重量
delay(500);
data_flash=heavy*price; // 总价=单价*重量
money=(unsigned int)data_flash;
if(exit) //如果进行了设置
{
exit=0;
//show() ; //显示刷新
}
display(heavy,alarm,jiao_zhun); //计算完成后送到液晶显示
delay(500);
chu_li(); //扫描函数
if(heavy>alarm) //重量超过上限报警
{
beep();
}
delay(500);
}
}
//外部中断解码程序
void intersvr1(void) interrupt 2 using 1
{
Tc=TH0*256+TL0; //提取中断时间间隔时长
TH0=0;
TL0=0; //定时中断重新置零
if((Tc>Imin)&&(Tc<Imax)) //定时器判断读取的启始码正确
{
m=0;
f=1;
return;
} //找到启始码
if(f==1)
{
if(Tc>Inum1&&Tc<Inum3)
{
Im[m/8]=Im[m/8]>>1|0x80; m++;
}
if(Tc>Inum2&&Tc<Inum1)
{
Im[m/8]=Im[m/8]>>1; m++; //取码
}
if(m==32)
{
m=0;
f=0;
if(Im[2]==~Im[3])
{
flag=1;
jian_ma=Im[2];
}
else flag=0; //取码完成后判断读码是否正?
}
if(jian_ma==0x15)
{
}
//准备读下一码
}
}
|
|