1、个人构想:如何为编程爱好者设计一款好玩的智能硬件(一)——即插即用、积木化、功能重组的智能硬件模块构想html
2、别人家的孩子:如何为编程爱好者设计一款好玩的智能硬件(二)——别人是如何设计硬件积木的!编程
3、MCU选型:如何为编程爱好者设计一款好玩的智能硬件(三)——该选什么样的MCU呢?网络
4、温湿度传感器DHT11驱动封装:ide
万事开头难,昨晚睡太晚!天天一篇确实有点累,不过能鞭策本身不偷懒努力向前!前三篇咱们已经将“X-积木”大体轮廓(第一篇)、同类产品(第二篇)、MCU选型及大体计划(第三篇最后)介绍了一下。前几篇属于宏观把控,本篇将实施第三篇最后的三步计划中的第一步——“暂选CC2541做为核心块,先实现几个简单的功能块(如温湿度模块、光照模块、显示屏模块、超声波模块、继电器模块、人体红外线模块等),并分别对各个外设模块封装成能够经过蓝牙获取其使用说明和通讯方式的API,而后尝试开发一个手机demo来经过蓝牙搜集这些信息并展现。”函数
包括本篇在内的接下来几篇都是针对各类常见外设进行和平台无关性封装,在每篇中会详细介绍每一个外设的特性及封装思路,而且在各类平台上进行验证。本篇介绍智能家居领域老是少不了的一款传感器——温湿度传感器post
买买买:url
有些朋友建议我“你讲软件咱们可以下载找到,你讲硬件咱们很难找到,若是方便给个连接吧”。所以从此我会在必要的地方插入如何购买这些元件的连接(不是广告植入哦!)。对于该款DHT11传感器只要在淘宝上输入关键词,即可搜到一片(我建议你们买那些销量比较高的,若是您不想跟风的话,能够深刻了解下所给的资料等是否齐全)。不过目前我不建议你们盲目地买过来,从此我会针对具体的小应用给你们一些采购方案~spa
传感器资料:设计
datasheet:http://akizukidenshi.com/download/ds/aosong/DHT11.pdfcode
DHT11 ①:是一个包含湿度测量电阻、NTC温度测量装置和一个8-bit的微处理器的温湿度采集模块。②:典型应用在加湿器、空调还有部分传感器网络中的气象采集等。③:特别说明其输出的是相对温湿度,须要校准!
Relative humidity Resolution: 16Bit Repeatability: ±1% RH Accuracy: At 25℃ ±5% RH Interchangeability: fully interchangeable Response time: 1 / e (63%) of 25℃ 6s 1m / s air 6s Hysteresis: <± 0.3% RH Long-term stability: <± 0.5% RH / yr in Temperature Resolution: 16Bit Repeatability: ±0.2℃ Range: At 25℃ ±2℃ Response time: 1 / e (63%) 10S
下面是其一个典型的小系统的电路图,其四个引脚的典型电器特性为:1, the VDD power supply 3.5~5.5V DC 2 DATA serial data, a single bus 3, NC, empty pin 4, GND ground, the negative power
从上面能够看出,其和MCU进行通讯的I/O引脚只有引脚2一根,因此要想正确从其中获取温湿度数据就必须了解其单线的通讯协议了!咱们的任务就是根据其通讯协议,编写一个平台无关的底层驱动!
通讯协议:
数据在DHT11和MCU之间采用单总线传输,一次传输40个bit,高位先出。
数据格式:
8bit湿度数据整数部分+8bit湿度数据小数部分+8bit温度数据整数部分+8bit温度数据小数部分+8bit奇偶校验
@这里的8bit奇偶校验=8bit湿度数据整数部分+8bit湿度数据小数部分+8bit温度数据整数部分+8bit温度数据小数部分
数据时序图:
上面咱们知道DHT11经过单总线将温湿度数据和奇偶校验总共40bit发送给主设备(通常是MCU),那么MCU如何发起、读取、并结束读数据这一过程的呢?要想知道这一过程最简单的方式即是看数据时序图(不少人讨厌看、胆怯看,是由于不了解它,其实它展现了整个通讯的详细过程,很美!)下面咱们就根据一个写好的DHT11的驱动程序,来反推这个时序图的精巧与美!
Step 1:系统上电启动后一秒DHT11趋于稳定,能够进行数据读取操做(因此系统刚启动时最好不要马上调用DHT11驱动函数读取数据
Step 2:初看该时序图,能够看出host设备置单总线一个凹槽型电平,造成开始读的初始信号!对于细节——置低必定要大于18ms。
Step 3:在主设备发起开始信号后便进入等待从设备应答模式,接下来当从设备将数据总线拉低持续80us而后又拉高80us后就准备发送40bit的数据了。
Step 4:接下来40bit的数据均是采用下面的格式发送过来,那么这40bit如何区分是1仍是0呢?以下:根据高电平持续的时间——当高电平持续30us如下表示该bit为0,若维持50-70us代表为1.这样就能准确得到这40bit的数据状况了,再加上最后8bit的奇偶校验,便更加加强了其可靠性!
Step 5:结束通讯,在40bit数据输出完毕低电平持续50us后置主设备为输出模式,置总线为高电平,结束本次通讯。
数据时序图对应的DHT11的驱动程序(只是从网上找的针对CC2541的):
从下面代码容易看出:step2阶段的代码和上面的时序图凹槽型几乎同样;step3阶段用while循环统计低电平和高电平持续时间(不过这里的驱动并无用这个持续时间);读8bit数据函数下面讲;step5阶段在52行端口属性设置为输出时真正生效,虽然上面27行已经将DATA_PIN置高,可是到52行才会生效,因此也知足40bit数据传输结束后50us后拉高电平结束本次数据传输。
1 void DHT11(void) //温湿传感启动 2 { 3 DATA_PIN=0; //启动阶段step2 4 Delay_ms(19); //>18MS 5 DATA_PIN=1; 6 P0DIR &= ~0x01; //从新配置IO口方向 7 Delay_10us(); 8 Delay_10us(); 9 Delay_10us(); 10 Delay_10us(); 11 if(!DATA_PIN) 12 { 13 ucharFLAG=2; //从设备应答阶段step3 14 while((!DATA_PIN)&&ucharFLAG++); 15 ucharFLAG=2; 16 while((DATA_PIN)&&ucharFLAG++); 17 COM(); //读取40bit阶段step4 18 ucharRH_data_H_temp=ucharcomdata; 19 COM(); 20 ucharRH_data_L_temp=ucharcomdata; 21 COM(); 22 ucharT_data_H_temp=ucharcomdata; 23 COM(); 24 ucharT_data_L_temp=ucharcomdata; 25 COM(); 26 ucharcheckdata_temp=ucharcomdata; 27 DATA_PIN=1; //和最后的52行组成end阶段step5 28 uchartemp=(ucharT_data_H_temp+ucharT_data_L_temp+ucharRH_data_H_temp+ucharRH_data_L_temp);//奇偶校验 29 if(uchartemp==ucharcheckdata_temp) 30 { 31 ucharRH_data_H=ucharRH_data_H_temp; 32 ucharRH_data_L=ucharRH_data_L_temp; 33 ucharT_data_H=ucharT_data_H_temp; 34 ucharT_data_L=ucharT_data_L_temp; 35 ucharcheckdata=ucharcheckdata_temp; 36 } 37 wendu_shi=ucharT_data_H/10; 38 wendu_ge=ucharT_data_H%10; 39 40 shidu_shi=ucharRH_data_H/10; 41 shidu_ge=ucharRH_data_H%10; 42 } 43 else //没用成功读取,返回0 44 { 45 wendu_shi=0; 46 wendu_ge=0; 47 48 shidu_shi=0; 49 shidu_ge=0; 50 } 51 52 P0DIR |= 0x01; //IO口须要从新配置 53 }
对于COM函数连续读8bit数据的细节以下:参照step4两种表示当前bit位为1仍是0的方法——第7行是用while循环过掉低电平状态(一样这里ucharFLAG做为统计低电平持续的时间并无用,这也体现了该驱动的不严谨性!),以后故意延时30us并检测当前是低电平仍是高电平,这里用的很机智!由于step4中两个时序图能够看出表示当前bit位为0的时序图高电平持续时间没有超过30us,表示1的时序图高电平持续了近70us,因此延时30us后再检测当前电平就能判断该bit位是0仍是1了!很机智吧!
1 void COM(void) // 温湿写入 2 { 3 uchar i; 4 for(i=0;i<8;i++) 5 { 6 ucharFLAG=2; 7 while((!DATA_PIN)&&ucharFLAG++); 8 Delay_10us(); 9 Delay_10us(); 10 Delay_10us(); 11 uchartemp=0; 12 if(DATA_PIN)uchartemp=1; 13 ucharFLAG=2; 14 while((DATA_PIN)&&ucharFLAG++); 15 if(ucharFLAG==1)break; 16 ucharcomdata<<=1; 17 ucharcomdata|=uchartemp; 18 } 19 }
小结&接下来计划:
本节将一款经常使用的DHT11温湿度传感器的购买、资料查找、datasheet阅读、时序图的理解和驱动代码的之因此这样写的缘由给你们展现出来。虽然是一款简单的单总线传感器,可是这种分析流程和方法和比较复杂的模块基本都是类似的。今天时间也有点晚了,我准备将该传感器和平台无关的驱动封装放在下一篇介绍,今天得早点休息啦~晚安,各位!明天同一时间、同一地点ヾ( ̄▽ ̄)再见~
@beautifulzzzz
2015-9-8 持续更新中~