///程序頭文件
#include <reg52.h>
//顯示函數頭文件
#include <display.h>
//宏定義
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
//管腳聲明
sbit LED_R= P3^4; //紅燈
sbit LED_Y= P3^5; //黃燈
sbit LED_G= P3^6; //綠燈
sbit Feng = P3^7; //蜂鳴器
//ADC0832
sbit CS0832=P1^7;
sbit CLK0832=P1^5;
sbit DI0832=P1^6;
sbit DO0832=P1^6;
//按鍵
sbit Key1=P3^0; //設置鍵
sbit Key2=P3^1; //加鍵
sbit Key3=P3^2; //減鍵
//函數聲明
extern uchar ADC0808();
extern void Key();
//延時函數,大約延時z ms
void delay(uint z)
{
uint i,j;
for(i=0;i<z;i++)
for(j=0;j<121;j++);
}
//煙霧含量變量
uchar temp=0;
/*指示燈變量 初始值*/
uchar GL=2; //2到14綠燈亮起
uchar YL=15; //15到29黃燈亮起
uchar RL=30; //29到255紅燈亮起
uchar FF=60; //蜂鳴器變量 大于60報警
uchar Mode=0; //按鈕模式|0 正常|1 G|2 Y|3 R|4 F|
void main() //主函數
{
Init1602(); //調用初始化顯示
while(1) //進入while循環(huán)
{
temp=ADC0808();//讀取AD數據
if(Mode==0) //正常模式時
{
Display_1602(GL,YL,RL,FF,temp); //顯示正常數據
if(temp>=GL&&temp<YL) //數值大于綠燈小于黃燈
{
LED_G=0; //綠燈亮
}
else //大于黃燈或小于綠燈
{
LED_G=1; //綠燈熄滅
}
if(temp>=YL&&temp<RL) //數值大于黃燈小于紅燈
{
LED_Y=0; //黃燈亮
}
else //大于紅燈或者小于黃燈
{
LED_Y=1; //黃燈熄滅
}
if(temp>=RL&&temp<=255)//滬指大于紅燈小于255
{
LED_R=0; //紅燈亮
}
else //小于紅燈
{
LED_R=1; //紅燈滅
}
if(temp>=FF&&temp<=255)//數值大于報警值
{
Feng=0; //蜂鳴器響
}
else //數值小于報警值
{
Feng=1; //蜂鳴器不響
}
}
Key(); //掃描按鍵函數
}
}
//ADC0832讀取信息
uchar GetValue0832(uchar Channel) //獲取數值返回。入口:通道(0或1)。出口:數值。
{
uchar i,Dat1=0,Dat2=0;
Clk0832=0;
Di0832=1;
Cs0832=0;
Clk0832=1;
Clk0832=0; //第一脈沖,開始位
Di0832=1;
Clk0832=1;
Clk0832=0; //第二脈沖,模式選擇
Di0832=Channel;//通道選擇,0或1
Clk0832=1;
Clk0832=0; //第三脈沖,通道選擇
Di0832=1; //釋放輸入線
for(i=0;i<8;i++) //從高到低取一次數
{
Clk0832=1; //下降沿有效
Clk0832=0;
if(Do0832) Dat1|=0x80>>i;
}
for(i=0;i<8;i++) //從低到高取一次數
{
if(Do0832) Dat2|=0x01<<i;
Clk0832=1; //下降沿有效
Clk0832=0;
}
Cs0832=1;
Di0832=1;
Clk0832=1; //數據讀取完成,釋放所有數據線
if(Dat1==Dat2)
return Dat1; //校驗兩次數相等,輸出
}
void Key() //按鍵函數
{
if(Key1==0) //模式選擇
{
delay(80); //延時去抖
while(Key1==0); //再次判斷
Feng=0; //蜂鳴器響
write_com(0x38);//屏幕初始化
write_com(0x0d);//打開顯示 無光標 光標閃爍
write_com(0x06);//當讀或寫一個字符是指針后移一位
Mode++; //模式加
switch(Mode) //判斷模式
{
case 1:
{
write_com(0x80+4);//選中位置閃爍
Feng=1; //蜂鳴器停止鳴響,形成按鍵音
break;
}
case 2:
{
write_com(0x80+9);//位置
Feng=1;
break;
}
case 3:
{
write_com(0x80+14);//位置
Feng=1;
break;
}
case 4:
{
write_com(0x80+0x40+4);//位置
Feng=1;
break;
}
case 5: //按5次后退出設置
{
write_com(0x0c);//打開顯示 無光標 無光標閃爍
Mode=0; //Mode清零
break;
}
}
}
if(Key2==0&&Mode!=0) //設置狀態(tài)時按下加鍵
{
delay(80); //延時去抖
while(Key2==0); //判斷按鍵
Feng=0; //蜂鳴器響
switch(Mode) //根據模式設置不同的值
{
case 1:
{
if(GL<YL-1) //綠燈比黃燈小1時,不可以減
{
GL++; //綠燈加
write_com(0x80+2); //寫入數據位置
write_data('0'+GL/100); //將綠燈拆字后顯示百位
write_data('0'+GL/10%10); //將綠燈拆字后顯示十位
write_data('0'+GL%10); //將綠燈拆字后顯示個位
write_com(0x80+4); //重新指定位置閃爍 下同
}
Feng=1;
break;
}
case 2:
{
if(YL<RL-1)
{
YL++;
write_com(0x80+7);
write_data('0'+YL/100);
write_data('0'+YL/10%10);
write_data('0'+YL%10);
write_com(0x80+9);//位置
}
Feng=1;
break;
}
case 3:
{
if(RL<255-1)
{
RL++;
write_com(0x80+12);
write_data('0'+RL/100);
write_data('0'+RL/10%10);
write_data('0'+RL%10);
write_com(0x80+14);//位置
}
Feng=1;
break;
}
case 4:
{
if(FF<255-1)
{
FF++;
write_com(0x80+0x42);
write_data('0'+FF/100);
write_data('0'+FF/10%10);
write_data('0'+FF%10);
write_com(0x80+0x40+4);//位置
}
Feng=1;
break;
}
}
}
if(Key3==0&&Mode!=0) //設置時按下減按鍵
{
delay(80);
while(Key3==0);
Feng=0;
switch(Mode)
{
case 1:
{
if(GL>0)
{
GL--;
write_com(0x80+2);
write_data('0'+GL/100);
write_data('0'+GL/10%10);
write_data('0'+GL%10);
write_com(0x80+4);//位置
}
Feng=1;
break;
}
case 2:
{
if(YL>GL+1)
{
YL--;
write_com(0x80+7);
write_data('0'+YL/100);
write_data('0'+YL/10%10);
write_data('0'+YL%10);
write_com(0x80+9);//位置
}
Feng=1;
break;
}
case 3:
{
if(RL>YL+1)
{
RL--;
write_com(0x80+12);
write_data('0'+RL/100);
write_data('0'+RL/10%10);
write_data('0'+RL%10);
write_com(0x80+14);//位置
}
Feng=1;
break;
}
case 4:
{
if(FF>0)
{
FF--;
write_com(0x80+0x42);
write_data('0'+FF/100);
write_data('0'+FF/10%10);
write_data('0'+FF%10);
write_com(0x80+0x40+4);//位置
}
Feng=1;
break;
}
}
}
}
//LCD管腳聲明
sbit LCDRS = P2^0;
sbit LCDRW= P2^1;
sbit LCDE= P2^2;
//初始畫時顯示的內容
uchar code Init1[]="welcome to ";
uchar code Init2[]="Lime Hous ";
//LCD延時
void LCDdelay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=10;y>0;y--);
}
//寫命令
void write_com(uchar com)
{
LCDRS=0;
LCDRW=0;
P0=com; //將數據寫入P0口
LCDdelay(5);
LCDEN=1;
LCDdelay(5);
LCDEN=0;
}
//寫數據
void write_data(uchar date)
{
LCDRS=1;
LCDRW=0;
P0=date; //將數據寫入P0口
LCDdelay(5);
LCDEN=1;
LCDdelay(5);
LCDEN=0;
}
//1602初始化
void Lcd1602_init()
{
uchar i=0;
write_com(0x38);//屏幕初始化
write_com(0x0c);//打開顯示 無光標 無光標閃爍
write_com(0x06);//當讀或寫一個字符是指針后一一位
write_com(0x01);//清屏
write_com(0x80);//設置位置1行1列
for(i=0;i<16;i++)
{
write_data(Init1[i]); //寫入一行數據
}
write_com(0x80+0x40);//設置位置2行1列
for(i=0;i<12;i++)
{
write_data(Init2[i]); //寫入二行數據
}
}
void Display_1602(uchar G,uchar Y,uchar R,uchar B,uchar Smog)
{
//綠色值顯示
write_com(0x80+2);
write_data('0'+G/100);
write_data('0'+G/10%10);
write_data('0'+G%10);
//黃色值顯示
write_com(0x80+7);
write_data('0'+Y/100);
write_data('0'+Y/10%10);
write_data('0'+Y%10);
//紅色值顯示
write_com(0x80+12);
write_data('0'+R/100);
write_data('0'+R/10%10);
write_data('0'+R%10);
//報警值顯示
write_com(0x80+0x42);
write_data('0'+B/100);
write_data('0'+B/10%10);
write_data('0'+B%10);
//當前值顯示
write_com(0x80+0x42+10);
write_data('0'+Smog/100);
write_data('0'+Smog/10%10);
write_data('0'+Smog%10);
}
|