#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++;
}
|