49-基于单片机的湿度和光照监测

时间:2024-12-03 07:07:17
#include <REGX52.H> #include<intrins.h> #include<stdio.h> #include "Delay.h" #include "LCD1602.h" #define uchar unsigned char #define uint unsigned int typedef unsigned char u8; typedef unsigned int u16; sbit CS=P1^0; //adc0832引脚 sbit CLK=P1^1; sbit DIO=P1^2; sbit beep=P3^4; sbit Temp_data=P2^6; //DHT11 sbit ssmotor = P3^0; unsigned char rec_dat_lcd0[6]; unsigned char rec_dat_lcd1[6]; unsigned char rec_dat_lcd2[6]; unsigned char rec_dat_lcd3[6]; unsigned int rec_dat[4]; static uchar u,U,R; //定义变量 static uchar sd; static int sdyz=80,gzyz=90; void DHT11_delay_us(unsigned char n); void DHT11_delay_ms(unsigned int z); void DHT11_start(); unsigned char DHT11_rec_byte(); void DHT11_receive(); void beep_warning(); void cshq(); void xxpxs(); //延时ms void DHT11_delay_ms(unsigned int z) { unsigned int i,j; for(i=z; i>0; i--) for(j=110; j>0; j--); } //延时us --2*n+5us void DHT11_delay_us(unsigned char n) { while(--n); } //DHT11起始信号 void DHT11_start() { Temp_data=1; DHT11_delay_us(10); Temp_data=0; DHT11_delay_ms(50);//这个延时不能过短,18ms以上,实际在仿真当中要想读到数据延时要在延时参数要在40以上才能出数据 Temp_data=1; DHT11_delay_us(30);//这个延时不能过短 } //接收一个字节 unsigned char DHT11_rec_byte() { unsigned char i,dat=0; for(i=0; i<8; i++) { while(!Temp_data); DHT11_delay_us(8); dat <<=1; if(Temp_data==1) { dat +=1; } while(Temp_data); } return dat; } //接收温湿度数据 void DHT11_receive() { unsigned int R_H,R_L,T_H,T_L; unsigned char RH,RL,TH,TL,revise; DHT11_start(); Temp_data=1; if(Temp_data==0) { while(Temp_data==0); //等待拉高 DHT11_delay_us(40); //拉高后延时80us R_H=DHT11_rec_byte(); //接收湿度高八位 R_L=DHT11_rec_byte(); //接收湿度低八位 T_H=DHT11_rec_byte(); //接收温度高八位 T_L=DHT11_rec_byte(); //接收温度低八位 revise=DHT11_rec_byte(); //接收校正位 DHT11_delay_us(25); //结束 if((R_H+R_L+T_H+T_L)==revise) //校正 { RH=R_H; RL=R_L; TH=T_H; TL=T_L; } /*数据处理,方便显示*/ rec_dat[0]=RH; rec_dat[1]=RL; rec_dat[2]=TH; rec_dat[3]=TL; } } void dht11() { DHT11_delay_ms(150); DHT11_receive(); sprintf(rec_dat_lcd0,"%d",rec_dat[0]); sprintf(rec_dat_lcd1,"%d",rec_dat[1]); sprintf(rec_dat_lcd2,"%d",rec_dat[2]); sprintf(rec_dat_lcd3,"%d",rec_dat[3]); DHT11_delay_ms(100); sd = rec_dat[1]*10 + rec_dat[0]; } uchar get_AD_Res() //ADC0832启动读取函数 { uchar i, data1=0, data2=0; CS=0; CLK=0;DIO=1;_nop_(); CLK=1;_nop_(); CLK=0;DIO=1;_nop_(); CLK=1;_nop_(); CLK=0;DIO=0;_nop_(); CLK=1;_nop_(); CLK=0;DIO=1;_nop_(); for(i=0; i<8; i++) { CLK=1;_nop_(); CLK=0;_nop_(); data1=(data1<<1)|(uchar)DIO; } for(i=0; i<8; i++) { data2=data2|(uchar)DIO<<i; CLK=1;_nop_(); CLK=0;_nop_(); } CS=1; return(data1 == data2)?data1:0; } void beep_warning()//蜂鸣器警报并且电机转动 { if(sd<sdyz) { beep = 1; ssmotor = 0; } else { ssmotor = 1; beep = 0; } } void main() //主函数 { LCD_Init(); //显示屏初始化 ssmotor = 1; beep = 0; do { cshq(); //参数获取 dht11(); //温湿度获取 xxpxs(); //显示屏显示 beep_warning(); //状态判断 } while(1); } void xxpxs() //显示屏显示 { LCD_ShowString(1,1,"gz:"); LCD_ShowNum(1,4,R,3); //CO LCD_ShowString(2,1,"sd:"); LCD_ShowNum(2,4,sd,3);//PM2.5 } void cshq() //参数获取 { u=get_AD_Res(); U=(250*u)/128; //此处将数字信号转化为模拟信号,要根据上拉电阻阻值来确定 R=200*U/250; //CO的值 }