///程序头文件
#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循环
{
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) //设置状态时按下加键
{
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);
}
|