#include<reg52.h> #define uchar unsigned char #define uint unsigned int unsigned char dispbuf[5]; unsigned char getdata[8]; // 存储八路模数转换后的结果; unsigned int temp; unsigned int temp1; unsigned char count; unsigned char d=0; char cancel=0; uchar number; uchar code warn[]={125,125,125,125,125,125,125,125};// 设定各个有害气体的指标; uchar codetd[]={0x04,0x14,0x24,0x34,0x44,0x54,0x64,0x74};// 通道先择数组; uchar code *gas[]={"CO ","NO","NO2 ","SO2 ", "SO3 ","CH4","C6H6 ","HCHO "}; // 有害气体名称; uchar code ok[]={"Everything isOK"}; sbit ST=P3^0; sbit OE=P3^1; sbit EOC=P2^3; sbit CLK=P3^3; sbit P32=P3^2; sbit P34=P3^4; sbit P35=P3^5; sbit P36=P3^6; sbit P37=P3^7; sbit rs=P2^0; //1602的数据/指令选择控制线 sbit rw=P2^2; //1602的读写控制线 sbit en=P2^1; //1602的使能控制线 sbit P23=P2^3; sbit BEEP=P2^7; sbit P17=P1^7; char flag=0; // 检测到指标高于设定值是flag=1; //数码管显示器// void delay1(uint z) //延时函数 { uint x,y; for(x=z;x>0;x--) for(y=122;y>0;y--); } void lcd_wcom(uchar com) //1602写命令函数 { rs=0; //选择指令寄存器 rw=0; //选择写 P1=com; //把命令字送入P2 delay1(5); //延时一小会儿,让1602准备接收数据 en=1; //使能线电平变化,命令送入1602的8位数据口 en=0; } void lcd_wdat(uchar dat) //1602写数据函数 { rs=1; //选择数据寄存器 rw=0; //选择写 P1=dat; //把要显示的数据送入P2 delay1(5); //延时一小会儿,让1602准备接收数据 en=1; //使能线电平变化,数据送入1602的8位数据口 en=0; } void lcd_init() //1602初始化函数 { lcd_wcom(0x38); //8位数据,双列,5*7字形 lcd_wcom(0x0c); //开启显示屏,关光标,光标不闪烁 lcd_wcom(0x06); //显示地址递增,即写一个数据后,显示位置右移一位 lcd_wcom(0x01); //清屏 } void write_str(uchar weizhi,uchar*neirong) //显示主函数 { uchar n,m=0; lcd_init(); //液晶初始化 lcd_wcom(0x80); //显示地址设为80H(即00H,)上排第一位 for(m=0;m<16;m++) //将table[]中的数据依次写入1602显示 { lcd_wdat(table[m]); delay(100); //延时 } lcd_wcom(0x80+0x40); //重新设定显示地址为,即下排第1位 for(n=0;n<16;n++) //将table1[]中的数据依次写入1602显示 { lcd_wdat(table1[n]); delay(100); //延时 } ucharm=0; lcd_wcom(weizhi); while(*neirong!=0) { lcd_wdat(neirong[m]); neirong++; delay1(5); } } void delay(uint time) { uintn,m,k; for(n=0;n<time;n++) for(m=0;m<50;m++) k++; } //定时器初始化// void TimeInitial() { TMOD=0x10; TH1=(65536-200)/256; TL1=(65536-200)%256; EA=1; ET1=1; TR1=1; } //八路模数转换存入getdata[]// void adc() { chari,m=1; for(i=0;i<8;i++) { P2=td[ i]|0x0f; ST=0; OE=0; ST=1; ST=0; delay(3); while(EOC==0); OE=1; getdata[m]=P0; OE=0; m++; } } //响铃程序// void alarm(void) { uchari; for(i=60;i>0;i--) { BEEP=~BEEP; delay(2); BEEP=~BEEP; delay(2); }
//自检程序// void test() { chari; for(i=0;i<8;i++) { P3=td[ i]; delay(800); P37=0; for(i=0;i<3;i++) { alarm(); delay(1500); } } } //检测程序// void check() { chari; for(i=1;i<=8;i++) { if(getdata[ i]>warn[i-1]) { flag=1; number=i; // 记录超过指标的通道; break; } else flag=0; } } //数据转换程序// void display() { temp=getdata[number-1]*1.0/255*500; dispbuf[4]='%'; dispbuf[3]=temp%10+0x30; // 取个位 ; dispbuf[2]=temp/10%10+0x30; // 取十位; dispbuf[1]='.'; dispbuf[0]=temp/100%10+0x30; // 取百位; write_str(0x80,gas[number-1]); // 显示; write_str(0x80+0x40,dispbuf); } //主函数// void main() { TimeInitial(); lcd_init(); EA=1; EX0=1; while(1) { adc(); check(); number = 3; flag = 1; while(flag==1) { lcd_wcom(0x01); display(); alarm(); flag= 0; adc(); check(); } number = 0; lcd_wcom(0x01); } } void main() { //test(); // 自检; P3=0xff; TimeInitial(); // 定时器初始化 lcd_init(); // 1602初始化 EA=1; EX0=1; while(1) { lcd_wcom(0x01); adc(); // 启动AD转换; check(); // 检查是否超标; cancel=0; while(flag==1) { P32=1; display();// 显示超过指标的信息; P3=td[number-1]; P37=0; if(cancel==0) // 判断停止报警按键是否按下 { alarm(); // 报警音 delay(1000); } P3=0x0f|td[number-1]; adc(); // 启动AD转换 check(); // 检查是否超标 } P37=1; //write_str(0x80,ok); cancel=0; } } //外部中断0中断服务程序// void inter(void) interrupt 0 using 1 { cancel=1; // 停止报警键按下, cancel=1; } //定时器0中断服务程序// void t1(void) interrupt 3 using 2 { TH1=(65536-200)/256; TL1=(65536-200)%256; CLK=~CLK; }
|