#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P1^0; //ds18b20与单片机连接口
sbit RS=P1^1; //液晶数据/命令选择端
sbit RW=P1^2;
sbit EN=P1^3; //液晶使能端
sbit lamp1 = P3^0;
sbit lamp2 = P3^1;
sbit p37=P3^6; //流量正常运行接口
sbit p36=P3^7; //温度报警接口
sbit p14=P1^4; //功能按键接口
sbit p15=P1^5;
sbit p16=P1^6;
uchar number[10]; //存储定时器IT0和IT1发出的频率
unsigned long int a,temp,temp2,temp4; //累计频率
float f,zong;
uint motorspeed, tvalue, counter=0; //脉冲数
uchar a1,a2,a3,a4,a5;//瞬时速度的个十百千万位
uchar v1,v2,v3,v4,v5; //瞬时速度的个十百千万位
uchar n1,n2,n3,n4,n5,n6,n7,n8,n9;
uchar tflag,d,g,kai,j,j1,j2,b;
uchar num,count,key1num,year,mouth,dat,hour,minute,sound;
uint temp1,temp3,temp5; //记录瞬时频率速度
uint d_flag;
uchar code table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x20}; //0-9数字和显示无
/************************延时子程序**************************/
void delay (uint z)
{
int x,y;
for(x=z;x>0;x--)
for(y=120;y>0;y--);
}
/***************延时1us子程序**********************/
void delay_18B20(unsigned int i)//延时1微秒
{
while(i--);
}
/***************液晶显示写指令*******************************/
void wr_com(unsigned char com) //写指令
{
delay(1); //延时1ms
RS=0; //写命令设置
RW=0; //并行数据的读写
EN=0; //使能为0
P2=com; //输入命令
delay(1); //延时1ms
EN=1; //使能为1
delay(1); //延时1ms
EN=0; //使能为0
}
/************液晶显示写数据**************************/
void wr_dat(unsigned char dat)//写数据
{
delay(1);
//延时1ms
RS=1; //写数据设置
RW=0; //并行数据的读写
EN=0; //使能为0
P2=dat; //输入数据
delay(1); //延时1ms
EN=1; //使能为1
delay(1); //延时1ms
EN=0; //使能为0
}
/***********水流量计算程序与数据转换程序******************/
void loop (uint flag,uint flag1)
{
uint zong1;
if(g==0) //判断时间是否到
{
zong =flag;
}
g=1; //将标志为为1
if(zong>=1000) //判断总流量后三位是否大于1000
{
a++; //总流量前六位加1
zong=0; //后三位清零
}
if(a>=1000000) //总流量前六位大于1百万
{
a=0; //总流量前六位清零
}
zong1=(int)zong ; //总流量后三位转换为整形
n9=a/100000; //总流量9位全部分配
n8=a%100000/10000;
n7=a%10000/1000;
n6=a%1000/100;
n5=a%100/10;
n4=a%10;
n3=zong1%1000/100;
n2=zong1%100/10;
n1=zong1%10;
//瞬时速度计算
a5 = flag1/10000%10;
a4 = flag1/1000%10;
a3 = flag1/100%10;
a2 = flag1/10%10;
a1 = flag1%10;
}
/***********水流量计算程序与数据转换程序******************/
void loop1(unsigned long int flag ,uint flag1)
{
unsigned long int zong1,sd;
int pos;
zong1=flag;
sd = flag1;
temp1=0;
temp3=0;
number[9] = zong1/100000000;
number[8] = zong1/100000000%10;
number[7] = zong1/10000000%10;
number[6] = zong1/1000000%10;
number[5] = zong1/100000%10;
number[4] = zong1/10000%10;
number[3] = zong1/1000%10;
number[2] = zong1/100%10;
number[1] = zong1/10%10;
number[0] = zong1%10;
delay(1000);
v5 = sd/10000;
v4 = sd/1000%10;
v3 = sd/100%10;
v2 = sd/10%10;
v1 = sd%10;
d_flag= 0;
// sd=sd;
}
void loopzong()
{
unsigned long int k;
uint V_z;
k=temp4+temp+temp2;
V_z=temp1+temp2+temp3;
temp1=temp2=temp3=0;
number[9] = k/100000000;
number[8] = k/100000000%10;
number[7] = k/10000000%10;
number[6] = k/1000000%10;
number[5] = k/100000%10;
number[4] = k/10000%10;
number[3] = k/1000%10;
number[2] = k/100%10;
number[1] = k/10%10;
number[0] = k%10;
delay(1000);
v5 = V_z/10000;
v4 = V_z/1000%10;
v3 = V_z/100%10;
v2 = V_z/10%10;
v1 = V_z%10;
}
void loopclock(uchar time,uchar x) //将时分秒写入屏幕
{
uchar shi,ge;
shi=time/10;
ge=time%10;
wr_com(0x80+0x40+x);
wr_dat(0x30+shi);
wr_dat(0x30+ge);
}
/**********************流量程序*******************************/
void liuliang()
{
while(d==20) //时间到?
{
d=0; //d清零
d_flag = 1;
b=TH0*256+TL0; //读取频率
temp4+=b;
temp5=b;
sound++;
if(sound==60)
{
sound=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==24)
{
hour = 0;
}
loopclock(hour,4);
}
loopclock(minute,7);
}
loopclock(sound,10);
if(b>=20&&b<40) //最小流量继电器一工作
{
lamp1 = 0 ;
lamp2 = 1;
}
else if(b*10>=80) //最大流量继电器2工作
{
lamp1 = 1;
lamp2 = 0;
}
else if(b*10>=40&&b*10<80) //到达额定值继电器一关闭
{
lamp1 = 1;
lamp2 = 1;
}
TH0=0x00; //计数器清零
TL0=0x00;
g=0; //时间标志位
}
}
/**************第一页显示子程序***************************/
void display1()
{
wr_dat(0x3a); //显示:
wr_com(0x80); //水流量(t)显示
wr_dat(0x46); //F
wr_dat(0x4c); //L
wr_dat(0x4f); //O
wr_dat(0x57); //W
wr_dat(0x31);
wr_dat(0x3a);
wr_dat(0x20);
wr_com(0x80+0x40);//空多少格
wr_dat(table[n9]);
wr_dat(table[n8]);
wr_dat(table[n7]);
wr_dat(0x2e); //显示小数点
wr_dat(table[n6]);
wr_dat(table[n5]);
wr_dat(table[n4]);
wr_dat(table[n3]);
wr_dat(table[n2]);
wr_dat(table[n1]);
wr_com(0x80+0x40+20);//空多少格
wr_dat(table[a4]);
wr_dat(table[a3]);
wr_dat(table[a2]);
wr_dat(table[a1]);
}
/**************第二页显示子程序**********************/
/*void display2()
{
// wr_dat(table[j2]); //价格的显示
// wr_dat(0x2e);
// wr_dat(table[j1]);
// wr_dat(0x5c);
// wr_dat(0x2f);
// wr_dat(0x74);
// wr_dat(0x20);
// wr_dat(0x20);
// wr_dat(0x20);
wr_dat(0x3a); //显示:
wr_com(0x80); //水流量(t)显示
wr_dat(0x46); //F
wr_dat(0x4c); //L
wr_dat(0x4f); //O
wr_dat(0x57); //W
wr_dat(0x32);
wr_dat(0x3a);
wr_dat(0x20);
} */
/**************第三页显示子程序**********************/
void display3()
{
wr_dat(0x3a); //显示:
wr_com(0x80); //水流量(t)显示
wr_dat(0x46); //F
wr_dat(0x4c); //L
wr_dat(0x4f); //O
wr_dat(0x57); //W
if(kai==1)
{
wr_dat(0x32);
}
if(kai==2)
{
wr_dat(0x33);
}
if(kai==3)
{
wr_dat(0x34);
}
wr_dat(0x3a);
wr_dat(0x20);
wr_com(0x80+0x40);//空多少格//水流量(kg)显示
wr_dat(table[number[9]]);
wr_dat(table[number[8]]);
wr_dat(table[number[7]]);
wr_dat(table[number[6]]);
wr_dat(table[number[5]]);
wr_dat(table[number[4]]);
wr_dat(table[number[3]]);
wr_dat(table[number[2]]);
wr_dat(table[number[1]]);
wr_dat(table[number[0]]);
wr_com(0x80+0X40+20);//空多少格
wr_dat(table[v5]);
wr_dat(table[v4]);
wr_dat(table[v3]);
wr_dat(table[v2]);
wr_dat(table[v1]);
wr_dat(0x2e); //显示小数点
wr_dat(0x20);
wr_dat(0x6b);
wr_dat(0x67);
}
/*****************控制流量测量的开关程序***********************/
void kaiguan1()
{
if(p14==0) //按键按下?
{
delay(2);
if(p14==0)
{
delay(2);
p36=~p36; //P3.6取反
// if(kai ==0)
// {
// TR0=~TR0; //TR0取反
// }
while(p14==0);//按键松开
}
}
}
/**************界面切换开关程序********************/
void kaiguan2()
{
if(p15==0) //按键按下?
{
delay(2);
if(p15==0)
{
delay(2);
// kai=~kai; //P3.6取反
kai++;
if(kai>=4)
{
kai = 0;
}
while(p15==0);//按键松开?
}
}
}
void kaiguan3()
{
if(p16==0) //按键按下?
{
delay(5);
if(p16==0)
{
key1num++;//时间设置键按下次数记录
while(p16==0);
switch(key1num)
{
case 1:
wr_com(0x80+0x40+11);//光标定位到秒位置
// wr_com(0x0f);//光标开始闪烁提示用户调整时?
break;
case 2:
wr_com(0x80+0x40+8);//光标定位到分钟位置
break;
case 3:
wr_com(0x80+0x40+5);//光标定位到小时位置
break;
case 4:
wr_com(0x0c);//取消光标闪烁
key1num=0;//按键次数统计归零,用于下一次统计
break;
}
// while(p16==0);//按键松开?
}
}
if(key1num!=0)
{
if(p14==0)
{
delay(5);//延时去抖
if(p14==0)
{
while(p14==0);//等待按键释放后才进行操作
switch(key1num)//根据key1num的值确定光标的位置,从而确定对时分秒的哪一个进行调整
{
case 1: //设置秒的值
sound++;
if(sound==60)
sound=0;
loopclock(sound,10);
wr_com(0x80+0x40+11);//将光标冲重新返回到秒的位置,因为写数据指针自动加
break;
case 2:
//设置分钟的值
minute++;
if(minute==60)
minute=0;
loopclock(minute,7);
wr_com(0x80+0x40+8);
break;
case 3:
//设置小时的值
hour++;
if(hour==24)
hour=0;
loopclock(hour,4);
wr_com(0x80+0x40+5);
break;
}
}
}
}
}
/**********************程序初始化******************************/
void lcd_init ()
{
//液晶使能端为0
wr_com(0x38); //液晶初始设置
wr_com(0x0c);
wr_com(0x06);
wr_com(0x01);
wr_com(0x40);
wr_dat(0x06); //写CGRAM写字模
wr_dat(0x09);
wr_dat(0x09);
wr_dat(0x06);
wr_dat(0x00);
wr_dat(0x00);
wr_dat(0x00);
wr_dat(0x00);
zong=0; //总流量(带小数点)
TMOD=0x15; //设定定时器0为计数功能,定时器为1为定时功能
TH1=(65536-50000)/256;//定时器1赋出值50ms
TL1=(65536-50000)%256;
TH0=0x00; //定时器0赋初值0次
TL0=0x00;
EN=0;
ET1=1; //开启定时器1中断
TR1=1; //开启定时器1
TR0=1; //开启计数器0
EX1=1; //开启外部中断0
IT1=1; //设置成下降沿触发方式
EX0=1; //开启外部中断0
IT0=1; //设置成下降沿触发方式
EA=1; //开启总中断
p16=1; //p16为1
p15=1; //p15为1
p14=1; //p14为1
zong=0; //总流量的后三位赋初值
a=0;
//总流量的前六位赋初值
j=20; //水价赋初值
j2=2; //水价个位赋初值
j1=0; //水价小数位赋初值
kai=0;
}
/********************主程序****************************/
void main()
{
int dt=100;
lcd_init(); //初始化显示
while(1)
{
kaiguan1(); //控制水流量的测量
kaiguan2(); //控制显示界面
liuliang(); //流量测量
switch(kai)
{
case 0:
wr_dat(0x01);
kaiguan3();
loopclock(hour,4); loopclock(minute,7); loopclock(sound,10);
// loop(temp4,temp5); //水流量计算程序与数据转换程序
// display1(); //显示第一页界面
break;
case 1:
wr_dat(0x01);
loop1(temp2,temp3);
display3(); //显示第三页界面
break;
case 2:
wr_dat(0x01);
loop1(temp,temp1);
display3(); //显示第三页界面
break;
case 3:
wr_dat(0x01);
loopzong();
display3(); //显示第三页界面
break;
}
}
}
/******************定时器1中断**********************/
void time1() interrupt 3
{
TH1=(65536-50000)/256;//定时器1初值定时50ms
TL1=(65536-50000)%256;
d++; //20ms后d加1
}
void _INT1() interrupt 2
{
temp++;
temp1++;
}
void _INT0() interrupt 0
{
temp2++;
temp3++;
}
|