DHT11温湿度.docx

上传人:b****5 文档编号:3830066 上传时间:2022-11-25 格式:DOCX 页数:19 大小:97.83KB
下载 相关 举报
DHT11温湿度.docx_第1页
第1页 / 共19页
DHT11温湿度.docx_第2页
第2页 / 共19页
DHT11温湿度.docx_第3页
第3页 / 共19页
DHT11温湿度.docx_第4页
第4页 / 共19页
DHT11温湿度.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

DHT11温湿度.docx

《DHT11温湿度.docx》由会员分享,可在线阅读,更多相关《DHT11温湿度.docx(19页珍藏版)》请在冰豆网上搜索。

DHT11温湿度.docx

DHT11温湿度

DHT11温湿度传感器

参数:

相对湿度:

分辨率:

0.1%RH      16Bit

精度:

25℃  正负 %2

温度:

分辨率:

0.1%RH      16Bit

量程范围:

25℃      正负0.2℃至 -40℃ ~-80℃

响应时间:

1/e(63%)      10S

电气特性:

供电DC3.5  -5.5V 电流 0.3mA 待机60uA

采样周期:

每次大于2秒

引脚说明

1、VDD   供电 3.5V-5.5VDC

2、DATA  串行数据,单总线,必须接上拉电阻 5.1K左右,这样空闲时 DATA总是为高电平

3、GND   接地,电源负极

4、NC    空脚

描述:

DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。

  它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有枀高的可靠性与卓越的长期稳定性。

传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能 8 位单片机相连接。

电路图:

引脚图

DHT11是通过单总线与微处理器通讯,只需要一根线,一次传送40位数据,高位先出。

数据格式:

8bit湿度整数数据 +8bit湿度小数数据 +8bint温度整数数据 +8bit温度小数数据 +8bit校验位

校验算法:

将湿度、温度的整数小数累加,只保留低8位。

微处理器(M0)与DHT11通信约定:

主从结构,DHT11为从机,M0作为主机,只有主机呼叫从机,从机才能应答。

详细流程:

M0发送起始信号->DHT响应信号->DHT通知M0准备接受信号->DHT发送准备好的数据->DHT结束信号->DHT内部重测环境温湿度数据并记录数据等待下一次M0的起始信号。

由流程可知,每一次M0获取的数据总是DHT上一次采集的数据,要想得到实时的数据,连续两次获取即可,官方不建议连续多次读取DHT,每次读取的间隔时间5秒就足够获取到准确的数据,上电时DHT需要1S的时间稳定。

M0起始信号:

1、设置DATA引脚为输出状态并输出高电平

2、再将DATA输出为低电平,持续时间大于18ms,此时DHT检测到后从低功耗模式->高速模式

3、DATA引脚设置为输入状态,由于上拉电阻的关系,DATA就变为高电平,从而完成一次起始信号。

C语言程序

1.voidstart()//开始信号 

2.

3.{ 

4.

5.  io=1; 

6.

7.  delay1(); 

8.

9.  io=0; 

10.

11.  delay(25);//主机把总线拉低必须大于18ms保证DHT11能检测到起始信号 

12.

13.  io=1;  //发送开始信号结束后拉高电平延时20-40us 

14.

15.  delay1();//以下三个延时函数差不多为24us符合要求 

16.

17.  delay1(); 

18.

19.  delay1(); 

20.

21.} 

DHT响应信号、准备信号:

(DHT在M0DATA引脚输出低电平时,从低功耗模式转至高速模式,等待DATA引脚变为高电平)

1、DHT输出80us低电平作为应答信号

2、DHT输出 80us高电平通知微处理器准备接受数据

3、连续发送 40位数据(上次采集的数据)

1.if(!

io)//判断从机是否有低电平响应信号// 

2.

3.  {  

4.    while(!

io);//判断从机发出80us的低电平响应信号是否结束// 

5.

6.    while(io);//判断从机发出80us的高电平是否结束如结束则主机进入数据接收状态 

7.

8.    R_H=receive_byte();//湿度高位 

9.

10.    R_L=receive_byte();//湿度低位 

11.

12.    T_H=receive_byte();//温度高位 

13.

14.    T_L=receive_byte();//温度低位 

15.

16.    check=receive_byte();//校验位 

17.

18.    io=0;//当最后一bit数据接完毕后从机拉低电平50us// 

19.

20.    for(i=0;i<7;i++)//差不多50us的延时 

21.

22.    delay1(); 

23.

24.    io=1;//总线由上拉电阻拉高进入空闲状态 

25.

26.    num_check=R_H+R_L+T_H+T_L; 

27.

28.    if(num_check==check)//判断读到的四个数据之和是否与校验位相同 

29.

30.    { 

31.

32.  RH=R_H; 

33.

34.  RL=R_L; 

35.

36.  TH=T_H; 

37.

38.  TL=T_L; 

39.

40.  check=num_check; 

41.

42.    } 

43.

44.  } 

45.

46.} 

DHT数据信号:

数据为“0”格式:

50us的低电平 +26-28us的高电平

数据为“1”格式:

50us的低电平 +70us的高电平

1.ucharreceive_byte()//接收一个字节// 

2.

3.{ 

4.

5.  uchari,temp; 

6.

7.  for(i=0;i<8;i++)//接收8bit的数据 

8.

9.  { 

10.

11.    while(!

io);//等待50us的低电平开始信号结束 

12.

13.    delay1();//开始信号结束之后延时26us-28us以下三个延时函数 

14.

15.      delay1(); 

16.

17.    delay1(); 

18.

19.    temp=0;//时间为26us-28us表示接收的为数据'0' 

20.

21.    if(io==1) 

22.

23.      temp=1;//如果26us-28us之后还为高电平则表示接收的数据为'1' 

24.

25.  while(io);//等待数据信号高电平'0'为26us-28us'1'为70us 

26.

27.    data_byte<<=1;//接收的数据为高位在前右移 

28.

29.      data_byte|=temp; 

30.

31.  } 

32.

33.  returndata_byte; 

34.

35.} 

DHT结束信号:

DHT的DATA引脚输出40位数据后,继续输出低电平50us后转为输入状态,由于上拉电阻,DATA随之变为高电平。

DHT内部开始重测环境温湿度数据,并记录数据,等待外部的起始信号。

完整程序

1.#include

2.#include

3.typedefunsignedcharBYTE;

4.typedefunsignedintWORD;

5.#defineuintunsignedint 

6.#defineucharunsignedchar 

7.sbitio=P1^0;//dht11data端接单片机的P1^0口// 

8.

9.sbitrw=P0^6;//一下三行是设置lcd1602的使能端// 

10.

11.sbitrs=P0^7; 

12.

13.sbitep=P0^5; 

14.

15.typedefbitBOOL;//此声明一个布尔型变量即真或假// 

16.

17.uchardata_byte; 

18.

19.ucharRH,RL,TH,TL; 

20.

21.

22.

23.//***************延时函数************************************* 

24.

25.voiddelay(ucharms)//延时模块// 

26.

27.{ 

28.

29.  uchari; 

30.

31.  while(ms--)            

32.

33.      

34.

35.for(i=0;i<100;i++); 

36.

37.} 

38.

39.

40.voiddelay1()//一个for循环大概需要8个多机器周期一个机器周期为1us晶振为12MHz也就是说本函数延时8us多此延时函数必须德稍微精确一点 

41.

42.{ 

43.

44.  uchari; 

45.

46.  for(i=0;i<1;i++); 

47.

48.} 

49.

50.  

51.

52.//***************************************************************  

53.

54.//lcd模块// 

55.

56.BOOLlcd_bz()//测试lcd忙碌状态返回值为布尔型数值真或假'1'.'0'  

57.

58.{ 

59.

60.BOOLresult;

61.  rs=0;        //读忙信号

62.  rw=1;

63.  ep=1;

64.  _nop_();

65.  _nop_();

66.  _nop_();

67.  _nop_();

68.  result=(BOOL)(P2&0x80);

69.  ep=0;

70.  result;

71.

72.}    

73.

74.voidwrite_cmd(ucharcmd)//写指令// 

75.

76.{ 

77.

78.  while(lcd_bz());

79.  rs=0;

80.  rw=0;

81.  ep=0;

82.  _nop_();

83.  _nop_();

84.  P2=cmd;

85.  _nop_();

86.  _nop_();

87.  _nop_();

88.  _nop_();

89.  ep=1;

90.  _nop_();

91.  _nop_();

92.  _nop_();

93.  _nop_();

94.  ep=0;

95.

96.} 

97.

98.

99.

100.voidwrite_addr(ucharaddr)//写地址// 

101.

102.{ 

103.

104.  write_cmd(addr|0x80);//LCD第一行的首地址为0x80第二行的首地址为0x80+0x40=0xc0 

105.

106.} 

107.

108.

109.

110.voidwrite_byte(uchardat)//写字节// 

111.

112.{ 

113.

114.  while(lcd_bz());

115.  rs=1;

116.  rw=0;

117.  ep=0;

118.  _nop_();

119.  _nop_();

120.  P2=dat;

121.  _nop_();

122.  _nop_();

123.  _nop_();

124.  _nop_();

125.  ep=1;

126.  _nop_();

127.  _nop_();

128.  _nop_();

129.  _nop_();

130.  ep=0;

131.

132.} 

133.

134.

135.

136.voidlcd_init()//lcd初始化// 

137.

138.{ 

139.

140.  write_cmd(0x38);//设置LCD两行显示一个数据由5*7点阵表示,数据由8跟线传输 

141.

142.  delay

(1); 

143.

144.  write_cmd(0x0c);//清除屏幕显示 

145.

146.  delay

(1); 

147.

148.  write_cmd(0x06);//设定输入方式增量不移位 

149.

150.  delay

(1); 

151.

152.  write_cmd(0x01);//开整体显示关光标不闪烁 

153.

154.  delay

(1); 

155.

156.} 

157.

158.

159.

160.voiddisplay(ucharaddr,ucharq)//在某一地址上显示内容adder表示的是地址偏移量q表示显示的字符或数字// 

161.

162.{ 

163.

164.  delay(10);  write_addr(addr); 

165.

166.  write_byte(q); 

167.

168.  delay

(1);//修改此时间可以改变LCD上数值跳变的数度 

169.

170.} 

171.

172.

173.

174.//**************************dht11测试某块*************************************// 

175.

176.voidstart()//开始信号 

177.

178.{ 

179.

180.  io=1; 

181.

182.  delay1(); 

183.

184.  io=0; 

185.

186.  delay(25);//主机把总线拉低必须大于18ms保证DHT11能检测到起始信号 

187.

188.  io=1;  //发送开始信号结束后拉高电平延时20-40us 

189.

190.  delay1();//以下三个延时函数差不多为24us符合要求 

191.

192.  delay1(); 

193.

194.  delay1(); 

195.

196.} 

197.

198.

199.

200.ucharreceive_byte()//接收一个字节// 

201.

202.{ 

203.

204.  uchari,temp; 

205.

206.  for(i=0;i<8;i++)//接收8bit的数据 

207.

208.  { 

209.

210.    while(!

io);//等待50us的低电平开始信号结束 

211.

212.    delay1();//开始信号结束之后延时26us-28us以下三个延时函数 

213.

214.      delay1(); 

215.

216.    delay1(); 

217.

218.    temp=0;//时间为26us-28us表示接收的为数据'0' 

219.

220.    if(io==1) 

221.

222.      temp=1;//如果26us-28us之后还为高电平则表示接收的数据为'1' 

223.

224.  while(io);//等待数据信号高电平'0'为26us-28us'1'为70us 

225.

226.    data_byte<<=1;//接收的数据为高位在前右移 

227.

228.      data_byte|=temp; 

229.

230.  } 

231.

232.  returndata_byte; 

233.

234.} 

235.

236.   

237.

238.voidreceive()//接收数据// 

239.

240.{ 

241.

242.  ucharT_H,T_L,R_H,R_L,check,num_check,i; 

243.

244.  start();//开始信号// 

245.

246.  io=1;  //主机设为输入判断从机DHT11响应信号 

247.

248.  if(!

io)//判断从机是否有低电平响应信号// 

249.

250.  {  

251.    while(!

io);//判断从机发出80us的低电平响应信号是否结束// 

252.

253.    while(io);//判断从机发出80us的高电平是否结束如结束则主机进入数据接收状态 

254.

255.    R_H=receive_byte();//湿度高位 

256.

257.    R_L=receive_byte();//湿度低位 

258.

259.    T_H=receive_byte();//温度高位 

260.

261.    T_L=receive_byte();//温度低位 

262.

263.    check=receive_byte();//校验位 

264.

265.    io=0;//当最后一bit数据接完毕后从机拉低电平50us// 

266.

267.    for(i=0;i<7;i++)//差不多50us的延时 

268.

269.    delay1(); 

270.

271.    io=1;//总线由上拉电阻拉高进入空闲状态 

272.

273.    num_check=R_H+R_L+T_H+T_L; 

274.

275.    if(num_check==check)//判断读到的四个数据之和是否与校验位相同 

276.

277.    { 

278.

279.  RH=R_H; 

280.

281.  RL=R_L; 

282.

283.  TH=T_H; 

284.

285.  TL=T_L; 

286.

287.  check=num_check; 

288.

289.    } 

290.

291.  } 

292.

293.} 

294.

295.//*****************************************************************************

296.

297.

298.

299.voidmain()//主函数模块// 

300.

301.{ 

302.

303.  lcd_init();//初始化LCD 

304.

305.  while

(1) 

306.

307.  { 

308.

309.  receive();//接收数据 

310.

311.display(0x00,'R');//LCD的第一行显示 

312.

313.display(0x01,':

'); 

314.

315.display(0x02,RH/10+0x30);//0x30表示带字库的LCD1602中0x30的位置放有数字0RH/10+0x30即表示湿度的十位数字在字库RH/10+0x30的位置处放着 

316.

317.display(0x03,RH%10+0x30); 

318.

319.display(0X04,'%'); 

320.

321.display(0x40,'T');//LCD的第二行显示 

322.

323.display(0x41,':

'); 

324.

325.display(0x42,TH/10+0x30); 

326.

327.display(0x43,TH%10+0x30); 

328.

329.display(0x44,0xdf);//以下两个是温度单位的处理 

330.

331.display(0x45,0x43); 

332.

333.  } 

334.} 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1