- #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( ); //显示程序
- }
复制代码 |