#ifndef __DHT11_H_
#define __DHT11_H_
#include "OLED.h"
#include <intrins.h> //用于提供_nop_();函数
#include <stdio.h>
//
//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位整型变量 */
//typedef signed int S16; /* defined for signed 16-bits integer variable 有符号16位整型变量 */
//typedef unsigned long U32; /* defined for unsigned 32-bits integer variable 无符号32位整型变量 */
//typedef signed long S32; /* defined for signed 32-bits integer variable 有符号32位整型变量 */
//typedef float F32; /* single precision floating point variable (32bits) 单精度浮点数(32位长度) */
//typedef double F64; /* double precision floating point variable (64bits) 双精度浮点数(64位长度) */
//
#define uchar unsigned char
#define uint unsigned int
//----------------------------------------------//
//----------------IO口定义区--------------------//
//----------------------------------------------//
sbit DHT11=P2^0;
//----------------------------------------------//
//----------------定义区--------------------//
//----------------------------------------------//
uchar U8FLAG,U8temp;
uchar U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
uchar U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
uchar U8comdata;
void Delay_ms(uint j) //ms延时子函数 如:20000ms=2s
{
uchar i;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}
}
void Delay_10us(void) //延时10us
{
uint i;
i--;
i--;
i--;
i--;
i--;
i--;
}
void COM(void) //接收一个字节
{
uchar i;
for(i=0;i<8;i++)//从高到低依次接收8位数据
{
U8FLAG=2;
while((!DHT11)&&U8FLAG++); //等待50us的低电平开始信号结束
Delay_10us(); //开始信号结束之后延时20us-30us
Delay_10us(); //以下三个延时函数差不多为 30us 符合要求
Delay_10us();
U8temp=0; //时间为20us-30us表示接收的为数据'0'
if(DHT11==1)U8temp=1; //如果20us-30us之后还为高电平则表示接收的数据为'1'
U8FLAG=2;
while((DHT11)&&U8FLAG++);//超时则跳出for循环
if(U8FLAG==1)break;
//判断数据位是0还是1
// 如果高电平高过预定0高电平值则数据位为1
U8comdata<<=1; //接收的数据为高位在前右移
U8comdata|=U8temp; //0
}//rof
}
//--------------------------------
//-----湿度读取子程序 ------------
//--------------------------------
//----以下变量均为全局变量--------
//----温度高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) //接收数据
{ /*********DHT11开始信号***********/
//DHT11=1; //电平拉高
//Delay_10us(); //延时10us
DHT11=0; //电平拉低
Delay_ms(180);//主机把总线拉低必须大于18ms 保证DHT11能检测到起始信号
DHT11=1; //发送开始信号结束后 拉高电平延时 20-40us
//总线由上拉电阻拉高 主机延时20us
Delay_10us(); //延时20-40us
Delay_10us(); //以下四个延时函数为 40us 符合要求
Delay_10us();
Delay_10us();
/*********DHT11开始信号***********/
DHT11=1; //主机设为输入 判断从机响应信号
if(!DHT11) //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
{
U8FLAG=2;
//判断从机是否发出 80us 的低电平响应信号是否结束
while((!DHT11)&&U8FLAG++);
U8FLAG=2;
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
while((DHT11)&&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; //校验位
//DHT11=0; //拉低延时10us
//Delay_10us();
DHT11=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; //校验位
display_GB2312_string(6,10,"on");
}//fi
else if(U8temp!=U8checkdata_temp) //如果与校验位不相同
{
display_GB2312_string(6,10,"off");
}
}//fi
}
void dqwdz(void) //读取温度值处理
{
uchar str1[2],str2[2];
RH(); //调用温湿度读取子程序
//湿度
str1[0]=U8checkdata/10; //湿度高位,十位
str1[1]=U8checkdata%10; //湿度高位,个位
// str2[0]=U8RH_data_L/10;
// str2[1]=U8RH_data_L%10;
//温度
// str2[0]=U8T_data_H; //温度高位,十位
// str2[1]=U8T_data_H; //温度高位,个位
// clear_screen(); //clear all dots 全屏清屏
display_GB2312_string(0,10,str1);
// //display_GB2312_string(2,10,str2);
//读取模块数据周期不易小于 1S
//注意:长时间的延时必须要有,不然会读出0
Delay_ms(20000); //延时2S
}
|