前言& _) T* @& Z5 Q$ a$ ]+ K
今天主要讲到DHT11温湿度传感器的应用,该传感器适用于多个场景,用途比较广泛,主要用来测量温度和湿度,其实对于单纯测量温度我们可以直接采用dsb18b20温度传感器,但是注意引脚接法,之前我不注意接反了,结果烧的······一碰手都直接起泡哈哈,好了,废话不讲,进入主题) g; Q+ U+ R( Z5 V8 {
! ^. @9 A8 U/ ` q6 _$ L6 O) Z! I
一、DHT11温湿度传感器, S8 A: W5 i6 h1 u; S2 T! T
DHT11传感器有四个接口,即VCC、GND、DATA、NC,那么首先要怎么接呢?其实这里面我们主要的就是接DATA这个口就行了,VCC、GND就不用多说了,NC端不接,悬空NC端即可,正常模块也是只有3个引脚引出来,所以只需要设定一个端口来与DATA互联就可以了
: X$ d8 _# L0 H% s4 v0 \4 H4 V, W* |$ A
3 u1 x9 a" ~/ V8 |
: p! q) y% G) i! m 我们发现实际上也就是如我上面所说的,它的四个引脚只需要利用三个就行了,而且该模块还有一块电源指示灯,当工作时会亮起。下面为原理图:0 T" @1 u4 o/ A1 P4 q, c
- Y' ?4 j5 H/ Y# I2 X
+ r: s, D- z, A" s. C) t" w0 [4 {2 n2 O6 N' I; e
那么在这里DATA只要随意连上STM32上一端口(下面我用到了PA11),设置为推挽输出即可,就可以实现数据互联。
8 P1 v0 n F4 i d) P0 ~
. C2 J! a3 M7 ^5 P
) N; K7 @* Q! [( @6 F
下面这里主要是对输出的流程的讲解,实际上如果看不懂也没事,后面可以通过代码加深对这几段话的理解
2 j" z: X% ]7 L" |* P: H$ b' S- i/ K7 Y0 J: R# e# x
6 l/ v t' R5 c* R
0 D- E6 C$ t6 F* B, p4 J U 二、实现测量主程序2 j% G: I) Q6 a1 \
DHT11函数(wenshi.c)" A9 j1 b% j) Z4 k" Y
$ _9 j; s# b3 @ x; X+ r- #include "delay.h"
3 T% e3 J7 S1 w J - #include "wenshi.h"& |8 o# C, ?$ o+ r/ C: u3 N
- 3 E3 \8 U0 Y; j5 t) r7 H
- #define DT GPIO_Pin_11
$ _/ L( |. u w+ E# W8 f/ u2 z0 P
' O$ {- d! N5 N$ V. g l- //复位DHT11
+ y- p: d2 r+ j* j. K! e! e% s - void DHT11_Rst(void)
0 c8 x2 R, j( M - {
6 S8 s+ v( P. i# K; r - DHT11_IO_OUT(); //SET OUTPUT+ j% m9 C0 M i8 A
- DHT11_DQ_OUT=0; //拉低
- m( s8 q) }2 _; v - delay_ms(20); //拉低延时至少18ms
9 U) m7 s: H! r; m) W7 Y - DHT11_DQ_OUT=1; //DQ=1,拉高 . }8 V3 p3 Q( e$ V- r8 m. m+ T' G
- delay_us(30); //拉高延时至少20~40us
% D4 I0 W. ~3 x/ @ - }
8 v6 E" _* G( H4 T1 N" r - : Y! J2 ~/ z7 r+ u b8 O+ x4 a" G
- //检测回应5 s8 w4 u. J& c+ w; S% n* F. h3 W1 t
- //返回1:检测错误
* G# R t5 M$ c; C/ y: k% a - //返回0:检测成功
9 T0 }% B& S3 R4 h+ m - u8 DHT11_Check(void) 3 v- i+ J* j9 m
- {
! N; n& S6 S( d1 k0 _9 y7 ^% a - u8 retry=0;! p6 P; W: ?: v/ U- @7 w" W
- DHT11_IO_IN();//SET INPUT
0 e1 \$ k2 g2 f+ [' S8 m - while (DHT11_DQ_IN&&retry<100)//DHT11拉低40~80us. k; {5 i2 w; g, ?5 X6 M3 @
- {- k4 c9 X) e) C$ N
- retry++;
" d# ^6 U0 u8 W2 M# M7 X" H - delay_us(1);
2 u! Y# ^. M+ R v - }; 8 _. D0 j2 g9 ^ I
- if(retry>=100)return 1;) @1 t# L5 A$ N- e
- else retry=0;
" Y0 Z* i* H" _7 C$ Z - while (!DHT11_DQ_IN&&retry<100)//DHT11再次拉高40~80us* @1 |6 b0 p- ~) f
- {* ~0 ~# j4 P |% O1 r9 s
- retry++;& \+ K6 Q/ X+ v& m) V% M X u
- delay_us(1);
1 o; {1 g5 J9 O) w V- D - };; F2 b4 E! `* f) G% q, G5 K0 ~
- if(retry>=100)return 1;
1 D; F* D6 H& K - return 0;& u7 }$ i; f1 G/ y
- }
" X, z$ M( j4 V# g" t
( }4 t+ e! w1 A$ ?0 r4 ]- //读取一个位Bit! R+ Q0 v0 C6 x M$ V
- //返回1或0- q$ P1 V8 _* y) u( l
- u8 DHT11_Read_Bit(void) 6 R m, {9 E2 ]4 |- l7 k
- {
9 r: S3 D( [' g5 Y6 s! V% U - u8 retry=0;
+ g. C5 J7 ?& } - while(DHT11_DQ_IN&&retry<100)//等待变低电平
" }+ Q3 Q' W& w; U+ i& M - {
; s% x. }% a3 {9 x7 q - retry++;% y5 }: ?8 P2 a" Q: [1 X3 e8 \
- delay_us(1);
- y: r0 P" b, `2 f5 J5 s - }; d; Q* ?: {/ y W
- retry=0;
' `5 z1 @0 q" C. G - while(!DHT11_DQ_IN&&retry<100)//等待变高电平- q6 P3 Z9 j: ]6 g" c& V0 g0 t8 y
- {
( X; z$ y* I- Z7 d) f - retry++;
( t# J0 q( F% o, c - delay_us(1);
) ]. P, G& z! e7 ?# }; h - }. b, C6 Y' Q; a; N9 v
- delay_us(40);//等待40us) `6 \+ Q0 U& _5 t% u, v" p2 w8 \. U
- if(DHT11_DQ_IN)return 1;) V4 }. i# D) n6 b$ M* d, z( V5 Z) i
- else return 0;
) z+ ^2 `# \8 {( `% |' H - }
, ?/ I5 F; T _/ q' y8 O - 7 X! i" p5 A& Z0 h* ` T% U) g# c4 x
- //读取一个字节$ ]! v% Y( ]: F( b7 l7 Z, \
- //返回读到的数据1 x1 o' L5 X4 h& b6 v6 h2 O
- u8 DHT11_Read_Byte(void)
8 ? R9 u k$ T o2 m - {
: ]$ Q- ~1 G! ^9 o - u8 i,dat;8 g. D: ^6 k5 _9 O* {2 d5 p
- dat=0;6 O0 \6 Q# D+ f( X8 h
- for (i=0;i<8;i++) 5 U* Y0 t- ~6 j. z- e) r
- {# n$ a3 i2 a3 A" ~7 T$ T
- dat<<=1;
: h" X& G3 i* s0 s4 E( U p7 N - dat|=DHT11_Read_Bit();, d" Z- g0 H* O j4 N1 ~
- }
9 w0 {. t. H! U* _ - return dat;6 ?/ q! k* a$ e! ]
- }% D7 c0 F7 j" v; o. }
0 I* ]! c. D h/ ]4 B- //DHT11读取一次数据
" r8 `* O* V) Z3 a1 Z" Z3 R# ` - //temp:温度(范围:0~50°)
/ U" a- Q4 c7 i7 K+ y8 h - //humi:湿度(范围:20%~90%)4 V3 @9 G+ V2 M% G8 Z3 |
- //tem:温度小数位
1 n; \0 N0 f* ] - //hum:湿度小数位
8 l5 F6 Y! Q) m/ k - u8 DHT11_Read_Data(u8 *temp,u8 *humi,u8 *tem,u8 *hum) ; w: e3 L. |, ?/ e# U& |4 T4 u
- {
- }0 V& b9 q u, w9 y# y7 G - u8 buf[5];8 M8 g9 g. K8 j, r1 z( z. a: m
- u8 i;
$ p0 o7 z( G6 h# _# _' |, ]! G* U( e8 H4 ^ - DHT11_Rst();
3 [. {2 \2 {0 q5 Q# L# J - if(DHT11_Check()==0)
0 G- d" d6 `4 z! S0 G0 f - {
; T5 j# r3 s1 N7 ` - for(i=0;i<5;i++)//读取40位字节
% s$ Z" p# q( [! F' Z - {
: `& [2 l' V$ r+ a - buf<i>=DHT11_Read_Byte();8 L1 [, D5 n0 I" Q+ e
- }
/ G( z; W' Z1 ?; y, ?- b) H6 u6 X - if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])( f2 L: H0 j3 Y# E& X7 u
- {/ E2 O- `) X5 p
- *humi=buf[0];- |. f% ^) o) i' }4 T2 `3 L: w8 t1 `
- *hum=buf[1];
& u5 r8 I- V8 ` - *temp=buf[2];6 E: Q, d4 Y: S& g
- *tem=buf[3];
- y% ^/ o$ q" v6 L - }3 [6 _7 {' t2 ~! ?
- }
4 k' u/ x( q2 U* w2 Z - else return 1;
F o8 O# }5 o0 y3 O' J+ s4 B - return 0; ; V3 u2 t5 \7 T3 g5 q+ r2 Q+ g
- }
5 s3 T# A) c) V& A* ~9 {' q - % L5 m( E5 m- V$ r3 @
- //初始化DHT11,同时检测是否连接上DHT11,PA11初始化
8 H# z' G: S! C0 k) S - 8 a9 l+ D! e7 |6 w5 N' D# d
- u8 DHT11_Init(void)
* z0 Y" g" X* L6 t, m - { $ z) q Z9 X7 X* l1 [
- GPIO_InitTypeDef GPIO_InitStructure; ! N& x+ M5 r: i' B9 f0 F! g0 ~
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); ) u M1 l8 {0 p& D$ M
- GPIO_InitStructure.GPIO_Pin = DT; //PA11/ F. z# s7 C' |4 J
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出" I% Z7 f2 s0 W8 ~; |2 r; ?& O0 r% B
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;- Z: u1 F! x* m) Z5 @' l( r
- GPIO_Init(GPIOA, &GPIO_InitStructure);
2 y$ @3 G/ x2 j: W$ i% z - GPIO_SetBits(GPIOA,DT);
7 u. [7 F( a" J: _ - * j& A! W* D! C* I% T3 d
- DHT11_Rst();
( K! E, @! c8 e9 f* e" S4 I& t - return DHT11_Check();
3 H3 [2 g7 X) v. E$ p9 r, ^ - }</i>
复制代码
4 z) z i2 g! v' }( A. f9 u9 Q: [& a
主函数(main.c)
# I5 V" @# |( @% o; b! r5 v5 ?8 u2 C) H
- #include "led.h"
! t; |- m+ b* O" J! ]+ L( d$ W - #include "delay.h"0 M8 `) w4 c n0 o+ g( X
- #include "key.h"9 m7 P" w( } H+ t6 f
- #include "sys.h"
9 d' h ]! P8 A; J' G - #include "lcd.h"
" Z/ C" I+ W8 k - #include "usart.h"+ t0 z. Q3 o! v/ q- c
- #include "wenshi.h"
! I# M" C0 _. k. w0 x% n0 r% a* m
6 H; ~0 @: W& k+ s3 L/ i- u8 temp;
' \, G9 k V' E2 ]- U - u8 humi;: N. b# A1 f8 x& `, K4 j
- u8 tem;
' t8 ?9 x" n2 T5 S3 b" N7 Q - u8 hum;, Y( v! H9 N9 W
- . O' s8 U3 L( D# L/ P/ r* i2 X
% b1 d0 P# w8 Q+ s! a- int main(void)
7 W( c1 k% S8 e* y }! ^5 n& v - {
6 w# m! ~' K1 u; v+ u
- s- a2 O3 N7 }& a" V2 H. E1 N- delay_init(); ( M6 g& _+ ^* U o- Y; ~
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
9 ?1 q0 {# @6 b. E7 q) R - uart_init(115200); ; M9 a" n/ T% e
- LED_Init(); //LED初始化) h% W- ^$ Z- W+ x0 X
- LCD_Init(); //LCD初始化
V, b/ V8 W" k! y - POINT_COLOR=RED; ' U$ f3 f% A I. ^/ f
- while(DHT11_Init())3 K+ r) H5 ]( K [& f" g+ b/ y
- {
; r% ^# B" [+ r' n) p5 R* d - printf("DHT11 Error \r\n");; c+ L8 ]2 ^# C3 g
- LCD_ShowString(20,20,210,16,16,"DHT11 Error"); 8 U% q* z5 y4 `" K) b# S7 p$ f; U
- delay_ms(1000);
2 `4 |+ j( I3 S1 K% O3 N - }
. A: R; L! C: R: M$ `, l - , I) ^4 K* P, u* d: Z4 Z* [& `4 p$ V
- while (1)
6 }# @8 G) I" y1 H - {
9 q. w* ] }8 n- b& ]' l. Q - DHT11_Read_Data(&temp,&humi,&tem,&hum);//取地址
O3 Y7 t' F( |+ {) e - " d' {# m( W! F7 W; J( U4 u( Q5 H
- LCD_ShowString(20,40,210,16,16,"temp:"); //分别显示所要显示的温度、湿度
1 r$ ?# M$ G ~: [ - LCD_ShowString(20,70,200,16,16,"humi:");1 p1 C6 }8 d8 t- {( H
- LCD_ShowString(90,40,110,8,16,".");# S5 x) p' b, z* T9 _
- LCD_ShowString(90,70,100,8,16,".");
- o ?8 C. m9 w+ I+ i - LCD_ShowNum(70,40,temp,2,16);! d0 K3 \+ s; i7 A% |: F: p
- LCD_ShowNum(70,70,humi,2,16);
' |1 d3 f: ?: x7 o0 _, m3 t6 H2 ~) ^ - LCD_ShowNum(95,40,tem,2,16);- U' T" [5 Z) ^
- LCD_ShowNum(95,70,hum,2,16);& W/ e& o- n+ X9 j H
- LED0=!LED0;
& j# ^9 l# T# w1 w' t - delay_ms(1000);: A5 V9 r7 L3 r/ T/ k
- }; j7 g1 R4 Q0 Q+ h
- }<i style="background-color: rgb(255, 255, 255);"> </i>
复制代码 3 m" z$ `# T7 ^) m$ f
LCD的代码就不列出来了,主要函数以及注释基本上已经到位了,希望对大家有所帮助!% u( ]6 J0 ]* _# `1 x0 Z
* w, g7 [: }- F% m# ~* v三、测试结果/ s4 l% Y! C0 v" B! p/ B
下图 为测试结果:: ~% d- `+ t8 u& C# ]( m8 o
& H @; s5 D9 O* |* T
$ P$ c+ A1 Y, |+ e c9 ]' b$ N7 t
+ E* r$ Q; B) ^9 r3 S
四、总结
7 z4 \% t; ]9 F1 G$ `/ O写到这里就接近尾声了,老规矩肯定不能忘哈哈,于晏老哥的话后面依旧续上,那么这里总结就再啰里啰嗦几句吧,DHT11是一款比较入门级且又十分耐用的温湿度检测模块,咱们要用到基本上学习期间也是在单片机上的运用学习
. c+ Y$ E4 `% W: ?# ]" b% c2 ^+ l
3 P1 K2 p2 N+ y- `- v* J9 g5 d; [- b4 w+ e: k( I
4 L* v- C- u# N% v$ O# z" P9 d |