- #include <reg52.h>
- #include<intrins.h>
- typedef unsigned int u16; //對數據類型進行聲明定義
- typedef unsigned char u8;
- sbit rs = P0 ^ 4; //LCD管腳
- sbit rw = P0 ^ 3;
- sbit e = P0 ^ 2;
- sbit trig=P1^4; //超聲波管腳
- sbit echo=P1^5;int i=0;
- unsigned char code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9','.','-','M'};
- u8 num[16]=' ';
- u8 yw[16]=' ';
- bit state; //讀狀態標志位
- u16 dis; //距離放在這里
- unsigned char code cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
- unsigned char buf[9] = {0};
- unsigned char nub = 0;
- unsigned int value = 0;
- unsigned char flag = 1;
- unsigned char w;
- sbit P2_0 = P2^0;
- bit nug;
- unsigned char shidu_int;
- unsigned char shidu_point;
- unsigned char tem_int;
- unsigned char tem_point;
- unsigned char check;
- unsigned char self_check;
- bit state;
- void delay5ms() //@11.0592MHz**************************延時函數
- {
- u8 i, j;
- i = 9;
- j = 244;
- do
- {
- while (--j);
- } while (--i);
- }
- void delay15ms() //@11.0592MHz
- {
- u8 i, j;
- i = 27;
- j = 226;
- do
- {
- while (--j);
- } while (--i);
- }
- void Delay12us() //@11.0592MHz
- {
- unsigned char i;
- _nop_();
- _nop_();
- _nop_();
- i = 30;
- while (--i);
- }
- void delay_ms(unsigned int ms) //延時
- {
- unsigned int i;
- unsigned char j;
- for(i=0;i<ms;i++)
- {
- for(j=0;j<200;j++);
- for(j=0;j<102;j++);
- }
- }
- bit read_busy() //讀狀態
- {
- e = 0;
- rs = 0;
- rw = 1;
- e = 1;
- state = P2 >> 7 | 0;
- delay5ms();
- e = 0;
- return state;
- }
- void write_cmd(unsigned char cmd) //寫指令
- {
- while(read_busy()); //等待lcd屏不忙
- e = 0;
- rs = 0;
- rw = 0;
- P2 = cmd;
- e = 1;
- delay5ms();
- e = 0;
- }
- void write_data(unsigned char date)
- {
- while(read_busy()); //等待lcd屏不忙
- e = 0;
- rs = 1;
- rw = 0;
- P2 = date;
- e = 1;
- delay5ms();
- e = 0;
- }
- void init_dht11()
- {
- //啟動dht11采集數據 《-》 初始化dht11
- P2_0 = 1;
- P2_0 = 0;
- delay_ms(20);
- P2_0 = 1;
- delay_ms(0.04);
- }
- unsigned char read_io()
- {
- unsigned char i;
- unsigned char date = 0;
- for(i = 0; i < 8; i++)
- {
- while(P2_0 == 0); //過掉50us的時間間隙
- nug = 0;
- delay_ms(0.03);
- if(P2_0 == 1)
- {
- nug = 1;
- }
- date = date << 1;
- date = date | nug;
- while(P2_0 == 1); //過掉收到的數據位為1的那段時間
- }
- return date;
- }
- void init_serial() //********************************************煙霧濃度模塊
- {
- //1.配置串口通信方式1 接收使能
- //SCON
- SM0 = 0;
- SM1 = 1; //配置串口通信的方式1
- REN = 1; //接收使能
- //2.配置波特率為9600
- TMOD = 0x20; //配置定時器1的工作方式2 8位自動重裝
- TH1 = 0xFD; //配置定時器計數寄存器高8位的重裝值
- TL1 = 0xFD; //配置定時器計數寄存器低8位的起始計數值
- TR1 = 1; //開啟定時器1
- EA = 1; //開啟總中斷
- ES = 0; //關閉串口中斷
- }
- void uart(void) interrupt 4
- {
- if(RI == 1)
- {
- buf[nub] = SBUF;//接收數據
- RI = 0; //清除接收標志位
- nub++;
- }
- if(nub == 9)
- {
- ES = 0; //關閉串口中斷
- if(buf[0] == 0xFF && buf[1] == 0x86)
- {
- value = buf[2] << 8 | buf[3]; //煙霧濃度值
- }
- nub = 0;
- flag = 1;
- }
- }
- void Timerinit() //初始化定時器 **********************************超聲波測距模塊
- {
- TMOD=0x01;
- TH0=0;
- TL0=0;
- }
- unsigned int distance() //算距離的函數
- {
- u16 y,z;
- echo=0;
- trig=1;
- Delay12us();
- trig=0;
- while(echo == 0);
- TR0 = 1;
- while(echo == 1);
- TR0 = 0;
- y=TH0*256+TL0; //計算高電平的時間
- z=(y*1.7)/100;
- TH0 = 0x00;
- TL0 = 0x00;
- return z;
- }
- void init_lcd() //初始化lcd屏幕
- {
- //1.延遲15ms
- delay15ms();
- //2.寫指令38H
- write_cmd(0x38);
- //3.延遲5ms
- delay5ms();
- //4.寫指令38H
- write_cmd(0x38);
- //5.延遲5ms
- delay5ms();
- //6.寫指令38H
- write_cmd(0x38);
- //7.以后每次寫指令、讀/寫數據之前均需檢測忙信號
- //8.寫指令38H:顯示設置模式
- //while(read_busy());
- write_cmd(0x38);
- //9.寫指令08H:顯示關閉
- //while(read_busy());
- write_cmd(0x08);
- //10.寫指令01H:顯示清屏
- //while(read_busy());
- write_cmd(0x01);
- //11.寫指令06H:顯示光標移動設置
- //while(read_busy());
- write_cmd(0x06);
- //12.寫指令0CH:顯示開及光標設置
- //while(read_busy());
- write_cmd(0x0C);
- }
- void xianshi( )
- {
- u8 i;
- init_serial();
- Timerinit(); //初始化定時器
- while(1)
- {
- dis = distance(); //****************************************距離
- for(i=4;i>0;i--)
- {
- num[i]=ASCII[dis%10];
- dis/=10;
- }
- write_cmd(0x80); //設置數據指針的位置
- write_data('J');
- for(i=0;i<5;i++) //寫數據
- {
- write_data(num[i]);
- }
- if(flag == 1) //*************************************煙霧濃度
- {
- //調用數碼管顯示函數display(value);
- write_cmd(0x80+0x08); //設置數據指針的位置
- write_data('Y');
- ES = 1; //關閉串口中斷
- for(w = 0; w < 9; w++)
- {
- SBUF = cmd[w];
- while(TI == 0); //等待數據發送完成
- TI = 0; //軟件清零 清除發送完成中斷標志位
- }
- write_data(SBUF/1000);
- write_data(SBUF%1000/100);
- write_data(SBUF%1000%100/10);
- write_data(SBUF%1000);
- flag = 0;
- ES = 0; //開啟串口中斷
- }
-
- //啟動dht11采集數據 《-》 初始化dht11 ******************************************溫濕度
- init_dht11();
- if(P2_0 == 0) //dht11響應了
- {
- while(P2_0 == 0); //過掉dht11的響應信號
- while(P2_0 == 1); //過掉dht11把總線拉高的80us
- shidu_int = read_io();
- shidu_point = read_io();
- tem_int = read_io();
- tem_point = read_io();
- check = read_io();
- self_check = shidu_int + shidu_point + tem_int + tem_point;
- if(check == self_check)
- {
- write_cmd(0x80+0x40); //設置數據指針
- write_data('S'); //顯示濕度
- //調用lcd顯示函數write_date()
- write_data(shidu_int/10);
- write_data(shidu_int%10);
- write_data(shidu_point/10);
- write_data(shidu_point%10);
- write_cmd(0x80+0x48); //設置數據指針
- write_data('W'); //顯示溫度
- write_data(tem_int/10);
- write_data(tem_int%10);
- write_data(tem_point%10);
- }
- }
- }
- }
- void main()
- {
- init_lcd(); //初始化顯示屏
- xianshi( ); //顯示程序
- }
復制代碼 |