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