<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>传感器 :: 标签 :: yafeng 的博客</title><link>http://yafengabc.github.io/tags/%E4%BC%A0%E6%84%9F%E5%99%A8/index.html</link><description/><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sat, 19 Sep 2026 14:36:30 +0800</lastBuildDate><atom:link href="http://yafengabc.github.io/tags/%E4%BC%A0%E6%84%9F%E5%99%A8/index.xml" rel="self" type="application/rss+xml"/><item><title>树莓派高级GPIO库，wiringpi2 for python使用笔记（四）实战DHT11解码</title><link>http://yafengabc.github.io/cnblogs/p5100741/index.html</link><pubDate>Tue, 05 Jan 2016 00:12:00 +0800</pubDate><guid>http://yafengabc.github.io/cnblogs/p5100741/index.html</guid><description>DHT11是一款有已校准数字信号输出的温湿度传感器。 精度湿度+-5%RH， 温度+-2℃，量程湿度20-90%RH， 温度0~50℃。&#10;我买的封装好的模块，上边自带了上拉电阻，直接查到树莓派上即可灰、紫、蓝分别代表数据、3.3V、0V,接到树莓派的3，1，10脚，分别对应PIN8，3.3V，0V。&#10;DHT11与单片机通讯协议为单线协议（1-wire），其实单线协议蛮厉害的，一个GPIO就能实现数据的读取，但是这个协议没有同步脉冲，所以对时序要求比较高，比如DHT11对高低电平定义如下：&#10;低电平50us，然后一个26-28us的高电平，代表0&#10;低电平50us，然后一个70us的高电平，代表1&#10;也就是说，需要能分辨出40us以下的时间才能准确的测出，下边看看具体的时序：&#10;总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。&#10;数字0表示如下图：&#10;数字1表示如下图：&#10;可以看出，每一位包括一开始的响应信号，都是由一个低电平跟一个高电平组成，其中响应信号为80us+80us=160us&#10;数字0为50+26=76us&#10;数字1为50+70=120us&#10;为读到DHT11的状态，我编写了以下的程序：&#10;import wiringpi2 as gpio owpin=8 #第8脚为1-wire脚 tl=[] #存放每个数据位的时间 gpio.wiringPiSetup() #初始化wiringpi库 gpio.pinMode(owpin,1) #设置针脚为输出状态 gpio.digitalWrite(owpin,1) #输出高电平 gpio.delay(1) ###发开始指令，要求DHT11传输数据 gpio.digitalWrite(owpin,0) #拉低25ms开始指令 gpio.delay(25) gpio.digitalWrite(owpin,1) #输出高电平，开始指令结束 gpio.pinMode(owpin,0) #设针脚为输入状态 ###开始指令发送完毕，把管脚设置为高电平，并等待DHT11拉低管脚。传输数据 while(gpio.digitalRead(owpin)==1): pass #如果管脚一直是1，则一直等待。 ###若被拉低，说明传输开始，应答信号+40位数据+结束标志共42位 ###下边共循环45次，故意多循环几次看结果。 for i in range(45): #测试每个数据周期的时间（包括40bit数据加一个发送开始标志 tc=gpio.micros() #记下当前us数（从初始化开始算起，必要时重新初始化） ''' 一个数据周期，包括一个低电平，一个高电平，从DHT11第一次拉低信号线开始 到DHT11发送最后一个50us的低电平结束（然后被拉高，一直维持高电平，所以 最后的完成标志是一直为高，超过500ms） ''' while(gpio.digitalRead(owpin)==0):pass #一位数据由一个低电平 while(gpio.digitalRead(owpin)==1): #加一个高电平组成 if gpio.micros()-tc&gt;500: #如果超过500us就结束了本次循环,传输结束后 break #会被上拉电阻拉成高电平，防止进入死循环 tl.append(gpio.micros()-tc) #记录每个周期时间的us数，存到tl这个列表 print(tl) #打印结果 程序里有详细的解释，我就不再赘述，这里贴出我这里的执行结果：</description></item></channel></rss>