树莓派控制DH11(温湿度传感器)

DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次 通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数 部分用于以后扩展,现读出为零.操作流程如下: 一次完整的数据传输为40bit,高位先出。

数据格式:数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和

数据传送正确时校验和数据等于“ 8bit湿度整数数据+8bit湿度小数数据 +8bi温度整数数据+8bit温度小数数据” 所得结果的末8位。
用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主 机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集, 用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集, 如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后 转换到低速模式。

总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必 须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后, 等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束 后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换 到输入模式,或者输出高电平均可, 总线由上拉电阻拉高

总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉 高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定 了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有 响应,请检查线路是否连接正常.当最后一bit数据传送完毕后,DHT11拉低总线 50us,随后总线由上拉电阻拉高进入空闲状态。

ps:

总线拉低18微妙是为了触发DH11能检测到起始信号,DH11检测到起始信号后,等待主机发起开始信号结束(主机拉高20-40us),之后引脚转为输入模式,然后DH11发送80us的低电平响应信号,之后DH11再把总线拉高80us准备发送数据,发送数据是根据高电平的长短来确定是1还是0,发送完一位数据后,都要把总线拉低50us的间隙 之后再发下一位。


#include<stdio.h>
#include<wiringPi.h>
#define PIN 11
int main()
{
	int i,j;
	unsigned long databuf = 0;  //存放温湿度内存
	unsigned char crc = 0;
//初始化wiringPi库
	if(wiringPiSetup() == -1)
	{
		printf("error wiringPi init\n");
		return -1;
	}
    //初始化引脚的工作模式
	pinMode(PIN,OUTPUT);
//初始化总线,拉高电平(只对这个温湿度而言,其它根据引脚的功能而定)
	digitalWrite(PIN,HIGH);//init 


	while(1)
	{
		delay(3000);
		pinMode(PIN,OUTPUT); 
		digitalWrite(PIN,LOW);//拉低电平,延时25ms(t1时刻),触发DH11起始信号(叫它准备工作)
		delay(25);
		digitalWrite(PIN,HIGH);//拉高电平,延时27us(t2时刻),主机开始发起结束信号
		//delayMicroseconds(27);
		pinMode(PIN,INPUT);    //设置为输入模式
		pullUpDnControl(PIN, PUD_UP);//启用上拉电阻,将不稳定的信号设为高电平,以免干扰
		
		delayMicroseconds(27);
		if (digitalRead(PIN) == 0)   //dh11拉低电平,延时80us(t3时刻),(功能:向主机发起响应信号)
		{
			while(!digitalRead(PIN))   //等待高电平(t4时刻)
				;
                //dh11初始化成功(获得数据)

                //开始传输前32位温湿度数据
			for(i=0;i<32;i++)          
			{
				while(digitalRead(PIN))  //等待低电平(t5时刻)
				;
				while(!digitalRead(PIN))//等待高电平(t6时刻)高电平的响应时长来判断是1或0
				;
				delayMicroseconds(32);
				databuf *=2;            //左移一位(左高右低)
				if(digitalRead(PIN)==HIGH)//延时32us后还是高电平 说明是1
				{
					databuf++;     //是1databuf加一
				}

			}
            //开始传输最后八位校验位
			for(i=0;i<8;i++)
			{
				while(digitalRead(PIN))//等待低电平(类t5时刻)
					;
				while(!digitalRead(PIN))/等待高电平(类t6时刻)高电平的响应时长来判断是1或0
					;
				delayMicroseconds(32);
				crc *=2;
				if(digitalRead(PIN)==HIGH)//延时32us后还是高电平 说明是1
				{
					crc++;
				}

			}
		}
//发送是先发低位依次到高位,高位还是高位,低位是否是低位,具体看大端还是小端模式
        //dh11前八位是湿度整数(最低位),之后八位是小数,在之后八位是温度整数,在之后八位是温度小数,最后八位是校验位(最高位),跟我们平时的读写习惯相反,左高又低
        //字节序较高位储存在字节序较低位,所以湿度整数存储在最低位,进行与运算有1的都为1,为0的都为零
		printf("RH:%d.%d\n",(databuf>>24) & 0xff,(databuf>>16) & 0xff);
		printf("TMP:%d.%d\n",(databuf>>8) & 0xff,databuf & 0xff);
		databuf = 0;
	}

	return 0;
}

运行结果: 

大端模式(Big-Endian):是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。

小端模式(Little-Endian):是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。数据的存储方向和我们的阅读习惯(方向)不一致。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值