#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit SCL=P2^1;//时钟脉冲
sbit SDA=P2^0;//双向输入输出数据端
#define SCL_SET SCL=1
#define SCL_CLR SCL=0
#define SDA_SET SDA=1
#define SDA_CLR SDA=0
#define AddWr 0x90 //写数据地址
#define AddRd 0x91 //读数据地址
#define adCon 0x40 //AD控制字节
sbit RS=P2^6;
sbit RW=P2^5;
sbit E=P2^7;
#define setRS RS=1
#define clrRS RS=0
#define setRW RW=1
#define clrRW RW=0
#define setE E=1
#define clrE E=0
uchar table1[]="Air is clean_AAA";
uchar table2[]="Air is clean_BBB";
uchar table3[]="Air is empoisonA";
uchar table4[]="Air is empoisonB";
uint time=0;
uchar ADFlag=0;
uchar num;
uchar str[8]="Ci n.mv ";
//延时1US
void delay(uint cnt)
{
while(--cnt);
}
//延时1MS
void delayms(uint time)
{
uint i;
for(i=0; i<time; i++)
delay(120);
}
//写数据,P0 1602
void writeData(uchar Data)
{
setRS;
clrRW;
delay(1);
setE;
delay(1);
P0=Data;
delay(5);
clrE;
}
//写命令,P0 1602
void writeCom(uchar Com)
{
clrRS;
clrRW;
delay(1);
setE;
delay(1);
P0=Com;
delay(5);
clrE;
}
//清屏函数 1602
void clear_scr(void)
{
writeCom(0x01);
delayms(5);
}
//写一个字符串在(X,Y )位置 1602
void disStr(uchar x, uchar y, uchar *str)
{
if(y==0) writeCom(0x80+x);//第一行
else writeCom(0xc0+x);//第二行
while(*str)
{
writeData(*str);
str++;
}
}
void disStr1()
{
writeCom(0xc0);//第2行
for(num=0;num<16;num++)
{
writeData(table1[num]);
delay(5);
}
delayms(10);
}
void disStr2()
{
writeCom(0xc0);//第2行
for(num=0;num<16;num++)
{
writeData(table2[num]);
delay(5);
}
delayms(10);
}
void disStr3()
{
writeCom(0xc0);//第2行
for(num=0;num<16;num++)
{
writeData(table3[num]);
delay(5);
}
delayms(10);
}
void disStr4()
{
writeCom(0xc0);//第2行
for(num=0;num<16;num++)
{
writeData(table4[num]);
delay(5);
}
delayms(10);
}
//LCD1602初始化
void lcdInitial()
{
writeCom(0x38);//显示模式设置
delayms(5);
writeCom(0x08);//显示关闭
clear_scr();//清屏
writeCom(0x06); //显示光标移动设置
delayms(5);
writeCom(0x0C); //显示开及光标设置
}
void start()
{
SDA_SET;
delay(1);
SCL_SET;
delay(5);
SDA_CLR;
}
void stop()
{
SDA_CLR;
delay(1);
SCL_SET;
delay(5);
SDA_SET;
}
void ack()
{
SDA_CLR;
SCL_SET;
delay(1);
SCL_CLR;
}
void noAck()
{
SDA_SET;
SCL_SET;
delay(1);
SCL_CLR;
}
void send(uchar Data)
{
uchar i=0;
uchar temp=0;
temp=Data;
for(i=0; i<8; i++)
{
SCL_CLR;
delay(1);
if(temp&0x80) SDA_SET;
else SDA_CLR;
delay(1);
SCL_SET;
delay(1);
temp<<=1;
}
SCL_CLR;
}
uchar recive()
{
uchar i=0;
uchar temp=0;
SDA_SET;//必须设置
for(i=0; i<8; i++)
{
SCL_CLR;//拉低允许数据改变
delay(1);
SCL_SET;//拉高保持数据,等待读走
delay(2);
if(SDA) temp|=0x01;
else temp&=0xfe;
if(i<7)
temp<<=1;//最低位发送完成不能移位,否则出错
}
SCL_CLR;
return temp;
}
uchar read(uchar ch )
{
uchar temp=0;
start();
send(AddWr);//确认芯片
ack();
send(adCon|ch);//确认通道
ack();
//读出数据,放进temp
start();
send(AddRd);
ack();
temp=recive();
noAck();
stop();
return temp;
}
void DAC(uchar light)
{
start();
send(AddWr);
ack();
send(0x40); //写入控制位,使能DAC输出
ack();
send(light);
ack();
stop();
}
void dis(uchar *date)
{
uchar i=0;
uchar ch1, ch2, ch3;
for(i=0;i<4;i++)
{
ch1=i+48; //通道显示位
str[1]=ch1;
ch2=date[i]/51+48; //整数位
//ch2=(date[i]*196+20)/10000;
str[3]=ch2;
ch3=date[i]%51/10+48; //十分位
//ch3=(date[i]*196+20)%10000/1000;
str[5]=ch3;
//if(i>1) disStr(i*8-16, 1, str);
disStr(i*8, 0, str);
//if((ch2<1)||(ch2=1&&ch3<5)) disStr1();
//else if((ch2=1&&ch3>=5)||(ch2=2&&ch3<5)) disStr2();
//else if((ch2=2&&ch3>=5)||(ch2=3&ch3<5)) disStr3();
//else disStr4();
}
}
void interrupt_init()
{
ET0=1;//定时器0溢出中断允许
TR0=1;//启动定时器0
TMOD=0X01;
TH0=0Xd8;
TL0=0Xf0;
EA=1;//开总中断
}
void main()
{
uchar i=0;
uchar vot[4];
interrupt_init();
lcdInitial();
//DAC(0);
while(1)
{
uchar date1;
if(ADFlag==1)
{
for(i=0; i<4; i++) vot[i]=read(i);
DAC(200);//DA转换函数,0-255渐暗
date1=vot[0];
}
dis(vot);
if(date1<115)
{
if(date1<88) disStr1();
else disStr2();
}
else
{
if(date1<160) disStr3();
else disStr4();
}
}
}
void tim0_() interrupt 1 using 1
{
TH0=0xd8; //重新赋值
TL0=0xf0;
time++;
if(time==100)
{
time=0;
ADFlag=1;
} //定时置位AD采样标志位
}