单片机驱动DHT11获取环境温湿度并在1602显示,同时可以调整温湿度的各自的上下限,有提示降温除湿功能。程序实测可用
原理图,Proteus仿真文件(需要8.5以上版本才能打开)都有:
单片机源程序如下:
- //http://www.51hei.com/bbs/dpj-51190-1.html
- #include <reg51.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- typedef unsigned char U8; /* defined for unsigned 8-bits integer variable 无符号8位整型变量 */
- typedef signed char S8; /* defined for signed 8-bits integer variable 有符号8位整型变量 */
- typedef unsigned int U16; /* defined for unsigned 16-bits integer variable 无符号16位整型变量 */
- sbit speek =P3^4; //报警
- sbit hh =P2^1; //高灯
- sbit ll =P2^2; //高灯
- sbit LCD_RS =P1^3;
- sbit LCD_RW =P1^4;
- sbit LCD_EN =P1^5;
- //sbit LCD_RS =P2^4;
- //sbit LCD_RW =P2^5;
- //sbit LCD_EN =P2^6;
- sbit setup =P1^6; // 设置+
- sbit setdown=P1^7; // 设置-
- sbit set =P3^0; // 设置
- sbit P2_0 =P1^0; //DHT11的DATE
- sbit P2_1 =P3^1; //串行总线---不用
- //----------------------------------------------//
- //----------------定义区--------------------//
- //----------------------------------------------//
- U8 U8FLAG;
- U8 U8count,U8temp;
- U8 U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
- U8 U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
- U8 U8comdata;
- U8 indata[5];
- U8 count, count_r=0;
- U16 U16temp1,U16temp2;
- uchar settem_h,settem_l,sethum_h,sethum_l,con=0;
- bit sethumbz_h=0,sethumbz_l=0,settembz_h=0,settembz_l=0,setkey;
- uchar i;
- bit BIAO;
- void Delay_1(U16 j) //100us延时
- {
- U8 i;
- for(;j>0;j--)
- {
- for(i=0;i<27;i++);
- }
- }
- //void elay(unsigned int num)//延时函数
- //{
- // while( --num );
- //}
- void Delay_10us(void) //进入函数3us
- {
- U8 i; //1us
- i--; //1us
- i--;
- i--;
- i--;
- i--;
- i--;
- }
-
- /********************************************************************/
- /* */
- /*检查LCD忙状态 */
- /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
- /* */
- /********************************************************************/
- bit lcd_busy()
- {
- bit result;
- LCD_RS = 0;
- LCD_RW = 1;
- LCD_EN = 1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- result = (bit)(P0&0x80);
- LCD_EN = 0;
- return result;
- }
- /********************************************************************/
- /* */
- /*写指令数据到LCD */
- /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
- /* */
- /********************************************************************/
- void lcd_wcmd(uchar cmd)
- {
- while(lcd_busy());
- LCD_RS = 0;
- LCD_RW = 0;
- LCD_EN = 0;
- _nop_();
- _nop_();
- P0 = cmd;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- LCD_EN = 1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- LCD_EN = 0;
- }
- /********************************************************************/
- /* */
- /*写显示数据到LCD */
- /*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
- /* */
- /********************************************************************/
- void lcd_wdat(uchar dat)
- {
- while(lcd_busy());
- LCD_RS = 1;
- LCD_RW = 0;
- LCD_EN = 0;
- P0 = dat;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- LCD_EN = 1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- LCD_EN = 0;
- }
- /********************************************************************/
- /* */
- /* LCD初始化设定 */
- /* */
- /********************************************************************/
- void lcd_init()
- {
- lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
- Delay_1(5);
- lcd_wcmd(0x38);
- Delay_1(5);
- lcd_wcmd(0x38);
- Delay_1(5);
- lcd_wcmd(0x0c); //显示开,关光标
- Delay_1(5);
- lcd_wcmd(0x06); //移动光标
- Delay_1(5);
- lcd_wcmd(0x01); //清除LCD的显示内容
- Delay_1(5);
- }
- /********************************************************************/
- /* */
- /* 设定显示位置 */
- /* */
- /********************************************************************/
- void lcd_pos(uchar pos)
- {
- lcd_wcmd(pos | 0x80); //数据指针=80+地址变量
- }
- void LCD1602PutStr(char* s)
- {
- uchar i = 0;
- while (*(i + s))
- {
- lcd_wdat(*(i + s));
- Delay_1(200);
- i++;
- }
- }
- void COM(void) //串行读一个字节数据
- {
- U8 i;
- for(i=0;i<8;i++)
- {
- U8FLAG=2;
- while((!P2_0)&&U8FLAG++); //自加254次 默认执行下面程序 50us低电平结束判断
- Delay_10us();
- Delay_10us();
- Delay_10us();
- U8temp=0;
- if(P2_0)U8temp=1;
- U8FLAG=2;
- while((P2_0)&&U8FLAG++);
-
- if(U8FLAG==1)break; //屏蔽
- U8comdata<<=1;
- U8comdata|=U8temp;
- }
- }
- //--------------------------------
- //-----湿度读取子程序 ------------
- //--------------------------------
- //----以下变量均为全局变量--------
- //----温度高8位== U8T_data_H------
- //----温度低8位== U8T_data_L------
- //----湿度高8位== U8RH_data_H-----
- //----湿度低8位== U8RH_data_L-----
- //----校验 8位 == U8checkdata-----
- //----调用相关子程序如下----------
- //---- Delay();, Delay_10us();,COM();
- //--------------------------------
- void RH(void)
- { TR0=0;
- //主机拉低18ms
- P2_0=0;
- Delay_1(180);
- P2_0=1;
- //总线由上拉电阻拉高 主机延时20us
- Delay_10us();
- Delay_10us();
- Delay_10us();
- Delay_10us();
- P2_0=1;
- //主机设为输入 判断从机响应信号
- if(!P2_0) //判断从机是否有低电平响应信号 如不响应则不读数据,响应则向下运行
- { //speek=0;
- U8FLAG=2;
- while((!P2_0)&&U8FLAG++);
- U8FLAG=2;
- while((P2_0)&&U8FLAG++);
- //数据接收状态
- COM();
- U8RH_data_H_temp=U8comdata;
- COM();
- U8RH_data_L_temp=U8comdata;
- COM();
- U8T_data_H_temp=U8comdata;
- COM();
- U8T_data_L_temp=U8comdata;
- COM();
- U8checkdata_temp=U8comdata;
- P2_0=1;
- //数据校验
-
- U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
- if(U8temp==U8checkdata_temp)
- {
- U8RH_data_H=U8RH_data_H_temp;
- U8RH_data_L=U8RH_data_L_temp;
- U8T_data_H=U8T_data_H_temp;
- U8T_data_L=U8T_data_L_temp;
- U8checkdata=U8checkdata_temp;
-
- }
- TR0=1;
- }
- }
- void Disp_Temperature()//显示温度
- {
- //unsigned char n=0;
- // display[4]=temp_data[0]&0x0f;
- // display[0]=ditab[display[4]]; //查表得小数位的值
- // display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
- Delay_1(200);
- lcd_pos(0x04);
- lcd_wdat('0'+U8RH_data_H/10); /* 显示湿度 */
- Delay_1(200);
- lcd_wdat('0'+U8RH_data_H%10);
- Delay_1(200);
- lcd_pos(0x44);
- lcd_wdat('0'+U8T_data_H/10); /* 显示温度*/
- Delay_1(200);
- lcd_wdat('0'+U8T_data_H%10);
- Delay_1(200);
- lcd_pos(9);
- lcd_wdat('0' + sethum_h / 10);
- Delay_1(200);
- lcd_wdat('0' + sethum_h % 10); /* 显示湿度上限 */
- Delay_1(200);
- lcd_pos(13);
- lcd_wdat('0' + sethum_l / 10);
- Delay_1(200);
- lcd_wdat('0' + sethum_l % 10); /* 显示湿度下限 */
-
- Delay_1(200);
- lcd_pos(0x49);
- lcd_wdat('0' + settem_h / 10);
- Delay_1(200);
- lcd_wdat('0' + settem_h % 10); /* 显示温度上限 */
- Delay_1(200);
- lcd_pos(0x4d);
- lcd_wdat('0' + settem_l / 10);
- Delay_1(200);
- lcd_wdat('0' + settem_l % 10); /* 显示温度下限 */
-
- if ((settembz_h==0)&&(settembz_l)&&(sethumbz_h)&&(sethumbz_l))
- {
- lcd_pos(0x4f); //消湿度下限的箭头
- lcd_wdat(' ');
- Delay_1(10);
- lcd_pos(0x0f);
- lcd_wdat(' ');
-
- }
- if (settembz_h)
- {
- lcd_pos(0x4f); //消湿度下限的箭头
-
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
基于51单片机的DHT11温湿度控制系统.rar
(2.05 MB, 下载次数: 345)
|