前言' i2 J! U& U \/ t. s8 ]
今天主要讲到DHT11温湿度传感器的应用,该传感器适用于多个场景,用途比较广泛,主要用来测量温度和湿度,其实对于单纯测量温度我们可以直接采用dsb18b20温度传感器,但是注意引脚接法,之前我不注意接反了,结果烧的······一碰手都直接起泡哈哈,好了,废话不讲,进入主题0 v6 a9 r3 t; G% b( N7 M- z3 Z
, G- V3 }" ?3 C一、DHT11温湿度传感器/ h! @, a. V& }* t! V1 T; ]
DHT11传感器有四个接口,即VCC、GND、DATA、NC,那么首先要怎么接呢?其实这里面我们主要的就是接DATA这个口就行了,VCC、GND就不用多说了,NC端不接,悬空NC端即可,正常模块也是只有3个引脚引出来,所以只需要设定一个端口来与DATA互联就可以了; c/ G: |; H. B
: H! Q! p( _- u, H6 v$ Z6 K
% f, p/ J# a0 m1 L9 Q2 m& r5 I# F/ u% Q$ H
我们发现实际上也就是如我上面所说的,它的四个引脚只需要利用三个就行了,而且该模块还有一块电源指示灯,当工作时会亮起。下面为原理图:: c* X V9 X- @, J( \3 ?& ] R
& ~8 N1 y' q8 q! q7 G- o1 J
! k" k8 Y" t: y
' _3 ?* ~$ I( _' t G# E
那么在这里DATA只要随意连上STM32上一端口(下面我用到了PA11),设置为推挽输出即可,就可以实现数据互联。
" m* Q) g% ^) h& G9 E
3 n% v3 M: o0 l* I! w! ^* g! G9 i
; V. M1 ?- U; E% L5 r; \
下面这里主要是对输出的流程的讲解,实际上如果看不懂也没事,后面可以通过代码加深对这几段话的理解" I$ F, f: ?/ t f/ b9 g( l* Y
0 i+ V! l4 b3 l2 `# o: m
1 X( g" K8 r, t1 f
/ q/ l7 ^8 t" ~- p) e4 U
二、实现测量主程序
# r1 T L, j& X* ]) m5 gDHT11函数(wenshi.c)
7 Z6 O, l+ |9 _6 w( J: s* M) t: d) {- ^ y8 b. M) S7 C# e# |
- #include "delay.h"5 v' q0 ?1 L! _ l+ d$ w
- #include "wenshi.h"
1 T, `2 N9 q3 ?0 t' K% D
, l% y4 s' ?7 {) V- #define DT GPIO_Pin_11, Y6 X w! e9 A) Y; I& C
' ?& P. m3 L2 O1 z9 l$ j3 c; Z- //复位DHT11
' U: p. P+ o4 E3 d0 A1 Q/ T, x - void DHT11_Rst(void) * O) p" J( ?' o
- { : u2 w/ |4 M% u9 ~* f2 u5 s
- DHT11_IO_OUT(); //SET OUTPUT6 W) U# O) n+ t- }' K; }
- DHT11_DQ_OUT=0; //拉低+ a# l! M0 G0 X6 l( r; f
- delay_ms(20); //拉低延时至少18ms: Z6 x' R5 {! X, G1 t8 q8 a2 H
- DHT11_DQ_OUT=1; //DQ=1,拉高 5 n. [0 b! Y; Y3 _! u& s7 O$ a
- delay_us(30); //拉高延时至少20~40us: O# d5 k8 f5 \6 {' w; _1 j ~2 n
- }
; h5 ~' l5 k( ^* q- z1 p
- J, a& T+ A% k8 ~6 {5 h- //检测回应3 M$ y/ S: s$ k3 v6 D3 b
- //返回1:检测错误
4 ^# G$ W: ^- c. C - //返回0:检测成功
- P1 K& J4 G) ?" J& e - u8 DHT11_Check(void) - [; C/ ^, u) ~# {: q
- {
/ V. q: t5 @3 Z% N5 ? e& N - u8 retry=0;
1 I( s4 Y' C" b; T! q - DHT11_IO_IN();//SET INPUT
. Y P( E5 j% p& X2 G0 W - while (DHT11_DQ_IN&&retry<100)//DHT11拉低40~80us7 e" p& l! E' U4 j) @8 c. d
- {
& D+ Z* [5 Q# u% A; F2 y/ L. H/ [ - retry++;
$ F3 ^1 _4 t) F" j( E - delay_us(1);7 g1 @; B7 F3 M; O8 ^$ b
- }; : M+ [7 g0 H- L+ q
- if(retry>=100)return 1;
. W i, {' V4 N8 T$ c) Q b - else retry=0;
1 I, G* x% a% \7 G! `9 E8 z+ @" Z - while (!DHT11_DQ_IN&&retry<100)//DHT11再次拉高40~80us6 Z9 S$ g, k" d1 z# ^
- {
4 v! U; u. }% P' K8 C/ J) y# S! H - retry++;& ?- n# \4 x" I" y8 r
- delay_us(1);$ n1 z4 [9 V8 ?. o: X, {+ }* q0 i
- };; `# ?' Y' G1 B9 M" T- N1 t: ? \
- if(retry>=100)return 1;
2 ~8 f9 {% W0 B' ~ p; X - return 0;
* _" P# S0 y! |* O) S - }
4 j) [3 M5 R/ e1 U
0 `. d( T; T) H, |- //读取一个位Bit
4 ?6 }3 }, C/ z) C' J - //返回1或06 O! U0 H1 g- e4 C
- u8 DHT11_Read_Bit(void)
; r+ ^& x. v8 q2 ?$ L8 v6 w - {( d2 `2 R. _6 c" i; `4 Y5 x
- u8 retry=0;; U- ]6 F4 V, y( n1 i8 |
- while(DHT11_DQ_IN&&retry<100)//等待变低电平& V7 O0 k" g1 e1 h9 ~' F
- {# q o' ]% _: Y9 d
- retry++;
{6 ?/ d. ]( q5 G2 ]/ a - delay_us(1);
& d1 e ~5 I. C( _2 m - }% W" t$ ?2 R; L9 w
- retry=0;
; |' k) v1 O3 E5 s, F$ P3 @+ w" r - while(!DHT11_DQ_IN&&retry<100)//等待变高电平
5 P: {0 _$ z6 l4 b0 j$ F7 V - {7 ~$ a( F$ W. H: y- e2 y6 p
- retry++;5 F$ M2 n& \) N7 C4 S1 c
- delay_us(1);: w P2 G* e6 E7 r% ]/ t
- }% p6 `; q4 z/ H, m% |( e* |
- delay_us(40);//等待40us
5 O$ \) M% w3 z - if(DHT11_DQ_IN)return 1;& O% ]' ^) c' D5 z- w" }6 D0 t
- else return 0;
2 C( G# Y2 z, S) \* R# h - }5 ~+ D1 B* ^ H% u: b# I
- & i' o. _9 c; g X% N6 Y3 A/ ~
- //读取一个字节
) K' T& J3 N4 y! ~9 I - //返回读到的数据
# n+ k- Q" `' l$ S - u8 DHT11_Read_Byte(void)
& n7 i' g2 r0 e" e3 Q- m. ? - {
" m7 }0 H# V3 O9 V. g - u8 i,dat;
5 s! n: D7 j5 G& |' E - dat=0;" O) _- s, H4 B/ b' q6 v C0 O% Z
- for (i=0;i<8;i++) ; ]" E* c s4 H
- {
( X( l2 x4 i) ^% F3 r0 s [$ { - dat<<=1;
6 g2 l( l7 i6 B' r/ N/ Z8 b0 U* F( O - dat|=DHT11_Read_Bit();( ?8 F6 y1 d" Z5 i/ r! a
- }
+ B( i0 S; G; j7 m/ ^ - return dat;
5 j/ z/ `' E$ N5 J; h7 q - }3 A9 s# y$ b" S! r; @ e! w
7 c; x+ b* z$ A' b6 l- //DHT11读取一次数据
+ \ C/ \ X9 [) r1 t) J; G - //temp:温度(范围:0~50°)2 |; I! R) H6 B8 D, p2 ]2 g
- //humi:湿度(范围:20%~90%)8 s, f% b! g6 g4 _, O7 J
- //tem:温度小数位
: X7 V; E1 T4 g - //hum:湿度小数位9 o- x5 H; Y$ w: H
- u8 DHT11_Read_Data(u8 *temp,u8 *humi,u8 *tem,u8 *hum)
+ I3 G5 r+ r: w% ` - { # D. \9 A) o4 @9 ~8 [/ a0 z' g
- u8 buf[5];
+ b9 R5 [" [5 c* {% G. Q- R) h - u8 i;6 K. X2 y4 B5 ?. E
- DHT11_Rst();
. r$ n, }, }) `+ ~: z' U/ S3 U - if(DHT11_Check()==0)
) J3 o# C( C, } - {
! C/ J* ^8 n0 I, ?! z0 b - for(i=0;i<5;i++)//读取40位字节
4 A! Z" h7 d2 l- s- {. m - {+ u! K N+ g2 ^
- buf<i>=DHT11_Read_Byte();+ G( b$ f+ D$ W- V. E
- }
5 A u8 M) E( z+ P h - if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])2 u6 O# _& w- l; T
- {
* E) |5 J( C0 @- ]6 X4 V% A- G - *humi=buf[0];
0 D3 g' H$ u% q+ p6 W U - *hum=buf[1];
! ]5 ^7 b9 k( C - *temp=buf[2];
' m" U g g C- E9 [% ^ - *tem=buf[3];& V/ G3 W# f/ m' ^9 c
- }
* D6 q/ R& |: ~ - }, e# W& Y, a% a, w' w. Q' Q" n
- else return 1;% a( L8 x3 A0 m! \- R
- return 0;
' `6 ?' u# D+ F p5 K7 M4 Y8 ^ - }& H/ j# W P; y$ V' v d
8 P4 ?5 \6 G2 M. G) g2 {- //初始化DHT11,同时检测是否连接上DHT11,PA11初始化/ d0 O1 z+ f7 d6 o; F
-
8 e7 o8 x, X3 @( G, _. f - u8 DHT11_Init(void)6 R" E T3 j- ~) z
- {
" s: U: j& A0 T) M( Y( l7 D- s - GPIO_InitTypeDef GPIO_InitStructure; " \# P3 T6 {4 l
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
% T8 _+ C4 a1 F/ r- M$ @0 E - GPIO_InitStructure.GPIO_Pin = DT; //PA11; ~2 X$ l4 M6 g; m2 |
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出# ^( m8 o; _( _' u& `. R
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
# G: P5 c/ q7 G4 P3 _& ? - GPIO_Init(GPIOA, &GPIO_InitStructure); 8 R4 M1 L" J5 F& A4 x! m6 D P
- GPIO_SetBits(GPIOA,DT); 5 ~( Y( ?$ O8 N' O c
-
9 |* ^7 ], U7 E5 F: z4 j! I4 Z O7 f. v - DHT11_Rst(); 1 B) h+ ]6 @6 U, G) v- j. U
- return DHT11_Check();
' V5 m. a* e0 l' N! W0 v2 R; l - }</i>
复制代码 6 X. ~: Y7 E. L* f, |5 E0 G8 P
. b% t. n- L% I$ I6 }/ S
主函数(main.c)( x/ j* K# Z- C4 ?( A8 ?2 k
% m5 |: H+ C) g- #include "led.h"
" G/ `) K4 X8 ]' O - #include "delay.h"
8 ~7 k6 x8 m5 \; ^ - #include "key.h"6 p# u4 Y7 s* m1 T2 r
- #include "sys.h"& Z6 s: o) M0 e( o4 W) E( r. V2 D
- #include "lcd.h"& i+ m- N1 [5 ]& X1 F* `$ U5 ~
- #include "usart.h"" `9 H+ Y" W6 j" t6 @; g# D
- #include "wenshi.h" }% ]3 F6 T4 ]8 S% Z% h# N
- + Y/ T/ ]) c6 V+ U# n
- u8 temp;1 {( U* d/ w; z! X7 P$ [ u% H
- u8 humi;8 s6 a1 c; T G) _( V. I
- u8 tem;
) H0 }3 O) A& K5 x/ ^, ^; @2 w - u8 hum;
% u8 e" v, X% S7 {1 v X - : }+ v' | y4 c
! X n2 E3 T$ W' ` n8 X* F( R& |- int main(void)
# P, l4 e t+ R - { ) Q, _1 f1 c9 ^+ p
- % n. Q% y, N) U9 W1 |
- delay_init(); - c" |& X; H! \; J' }
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 9 X; ^7 X+ q+ F, {* i' q
- uart_init(115200);
& v2 H- S: X* h - LED_Init(); //LED初始化2 b. O/ m6 |* X! c5 d9 P
- LCD_Init(); //LCD初始化/ x9 G2 O# z; \4 C4 l) K
- POINT_COLOR=RED; * r+ C% J0 ^ b; i) H" R" c
- while(DHT11_Init())) `$ p% R8 N$ y) b
- {% Z: C+ M( c' ^; m
- printf("DHT11 Error \r\n");
$ A5 c! L4 g' L- m' x- C$ y - LCD_ShowString(20,20,210,16,16,"DHT11 Error"); ' d* _' f- j3 x6 w6 N
- delay_ms(1000);( {: @8 J, j; z' m0 _
- }* C( u+ l3 V" C) P& ~( f
- 6 k6 ?# V- ` ]! J+ s! L
- while (1)8 D, w+ l! Q1 a! V& ]1 Q
- {3 O' j& Y, P5 D& D
- DHT11_Read_Data(&temp,&humi,&tem,&hum);//取地址! c# o B' B% K3 u' k6 Z9 [
- ' i/ f5 h9 o6 X- V- q. y8 O
- LCD_ShowString(20,40,210,16,16,"temp:"); //分别显示所要显示的温度、湿度$ c% O' o- o1 D( \ W: C) x
- LCD_ShowString(20,70,200,16,16,"humi:");1 Z! k* b0 g8 }, X4 z
- LCD_ShowString(90,40,110,8,16,".");6 @# Q5 h# f# k. p
- LCD_ShowString(90,70,100,8,16,".");
4 j6 t! g q# B1 @ - LCD_ShowNum(70,40,temp,2,16);
2 _3 e k9 t0 {# v6 o3 p* i& @ - LCD_ShowNum(70,70,humi,2,16);3 m* ~- W$ K4 K" ]( a0 _: G0 S
- LCD_ShowNum(95,40,tem,2,16);
% d% x, v% Z, r - LCD_ShowNum(95,70,hum,2,16);
. K* M3 K! f# v; x$ S9 D2 G7 p - LED0=!LED0;
* [5 ]( v, t0 a1 C/ ]# e3 h - delay_ms(1000);
# i+ J% k q, { - }
, I# N" I3 x- u, a( p - }<i style="background-color: rgb(255, 255, 255);"> </i>
复制代码 $ j2 ?* e( V, R2 `0 J6 R! z
LCD的代码就不列出来了,主要函数以及注释基本上已经到位了,希望对大家有所帮助!% k. e7 M1 ^3 M/ a8 K( f h* G# s
. C8 E- o3 p+ @0 p( B三、测试结果* V* G1 J9 D+ w1 ?
下图 为测试结果:
( s, B* w! M d! n, b+ k9 O8 W/ G( \7 _) I# d) B r2 M& b; V
5 \ a+ H/ z5 c; g T- i& K& \1 B( K# C( w5 E
四、总结
2 V" \) b3 s6 _- f" ]0 q/ z写到这里就接近尾声了,老规矩肯定不能忘哈哈,于晏老哥的话后面依旧续上,那么这里总结就再啰里啰嗦几句吧,DHT11是一款比较入门级且又十分耐用的温湿度检测模块,咱们要用到基本上学习期间也是在单片机上的运用学习
$ c! D+ k% V% n, c
* `, B$ Q7 I7 }4 w
' u( Z& t( h4 p. a
2 C5 u* C& I m$ t4 \ |