|
1.DHT11简介 DHT11是一款温湿度一体化的数字传感器,该传感器包括一个电阻式测湿元件和一个NTC测温元件,并与一个高性能8位单片机连接。通过单片机微处理器简单的电路连接就能够实时的采集湿度和温度。DHT11与STM32之间能采用简单的单总线进行通讯,仅需一个IO口。传感器内部温度和湿度数据40个bit的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。 DHT11采用单总线数据格式,即单个数据引脚端口完成输入输出双向传输。其数据包由5个字节(40Bit)组成。数据分小数和整数部分,一次完整的数据传输为40bit,高位先出。数据格式如下图示
6 F0 ~2 `+ ]7 s0 Y _4 M( O. ?
8 ~ x1 y9 m/ Z
根据以上数据,即可算出温度和湿度的值,计算方法如下: 湿度 = byte4.byte3 温度 = byte2.byte1 校验 = byte4 + byte3 + byte2 + byte1
. Q9 E \, a$ k W5 o
DHT11和单片机的一次通讯最大为3ms左右,建议主机连续读取时间间隔不要小于100ms,下面是DHT11的三种时序: - c5 c1 G) |% \. E$ V5 ]2 _
⏩ 数据发送时序 首先主机发送开始信号,即拉低数据线保持t1(至少18ms)时间,接着拉高数据线t2(20 ~ 40us)时间;然后读取DHT11的响应,正常的话DHT11会拉低数据线并保持t3(40 ~ 50us)时间作为响应信号,接着DHT11拉高数据线并保持t4(40 ~ 50us)时间后,开始传输数据 ) F6 g& b: W" O# F
% u* e% t9 n+ j; T2 v' t. s5 C
⏩ DHT11输出0时序 9 o4 e% o2 ^: @+ N$ m7 ]
9 ?( h8 `( h5 a
⏩ DHT11输出1时序
6 S7 h/ a& T2 d
5 A) v, Y+ d0 r+ l3 Z0 F! \
" @# z# n7 t; U1 r' A$ V2.硬件设计 p- y" v. H5 O& O4 J$ p/ X
D1指示灯用来提示系统运行状态,DS18B20温度传感器用来检测环境温度,串口1用来打印温度值 指示灯D1 USART1串口 PG11 TIM7(提供us延时)
) c+ ^3 Q- h, A: ?" _6 @( B
: b6 N. E! e l4 v- P* g3.软件设计 3.1 STM32CubeMX设置
" m$ Q8 u3 ~$ D8 i3 z
➡️ RCC设置外接HSE,时钟设置为72M 6 L" `+ c( c: C# p9 Q
➡️ PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平 ; E% N: y6 N6 O# v
➡️ USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位
; S6 j6 c* _' V4 o$ C$ P* F9 _7 P
➡️ PG11设置为GPIO推挽输出模式、上拉、高速 4 \: i( [( \9 c1 N7 l
➡️ 激活TIM7,预分频因子设为72-1,向上计数,自动重载值为65535;因此计数器CNT_CLK = 1MHz,计数器周期为1us
) \% ?" f7 L+ M) N p' o
% b" |9 F9 O5 \+ q4 B z0 t
➡️输入工程名,选择路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码
! J% x9 O# o" U$ a7 U+ X' u8 s3.2 MDK-ARM软件编程 ( U4 |4 X3 t" g" X4 {
➡️ 在tim.c文件下实现微秒延时(us)函数 - void delay_us(uint16_t us){# d0 `: l. D; H& p5 }+ l/ k. Q
- uint16_t differ = 0xffff-us-5; j# }% W3 x- `. _8 y) |
- //设定TIM7计数器起始值 6 }3 @$ K- s8 k' V5 w* ]5 A$ T/ B% }
- __HAL_TIM_SET_COUNTER(&htim7,differ);
. D$ v8 x1 u5 {* B/ o9 `6 L - //启动定时器
# p. L: e5 G: ]$ G! M+ P - HAL_TIM_Base_Start(&htim7); / U% T& K: \6 R, M, e! T% s2 b
- + D w% w) s4 _: d2 @! w/ J; j( w
- while(differ < 0xffff-5){ //判断
, @8 L0 {0 M1 p1 x6 F - //查询计数器的计数值: U+ ]/ I0 o' p. Q1 {
- differ = __HAL_TIM_GET_COUNTER(&htim7); $ k/ T& ^/ V9 i# z
- }6 }" J% b* R# V8 l4 Y
- HAL_TIM_Base_Stop(&htim7);
0 k4 d: v- n4 n2 z1 p/ u! m/ d) F0 c - }
复制代码 9 ~5 k: p) B' s. J6 {
➡️ 创建DHT11温湿度传感器驱动文件DHT11.c 和相关头文件DHT11.h - void DHT11_IO_IN(void){ //IO口方向设置为输入 I5 `! k7 ^8 r( |1 i
- GPIO_InitTypeDef GPIO_InitStructure;
) [* q& @7 e6 Q5 ]5 W - GPIO_InitStructure.Pin = GPIO_PIN_11;
( T' H7 w& H) o- @- y' ^ - GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
& Z& m8 U. g! w7 \ H - HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);" S* m$ l$ D" X* W9 s
- }
" v8 m& H4 [) T) Z- F3 W - 5 E! V- {( R( j( Y( x2 r
- void DHT11_IO_OUT(void){ //IO口方向设置为输出
% ^; E+ u; K6 y - GPIO_InitTypeDef GPIO_InitStructure;
# k5 t9 E e8 F r - GPIO_InitStructure.Pin = GPIO_PIN_11;% B% q# _0 Z8 F, C& \; t- g8 x
- GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
/ `- U( |8 M) U& B" T4 l# ]0 l - GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;; x' `. M+ W8 X: i/ @+ @0 ~$ L
- HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);
+ `9 R2 x6 l% q/ Z. E9 y( I; h8 H - }: Z: f' s6 Z; e
- 7 Q' v$ e! v \$ x
- void DHT11_Rst(void){ / s9 Y o4 p& \" t/ c
- DHT11_IO_OUT(); //设置为输出2 K; X/ a" N: @
- DHT11_DQ_OUT_LOW; //拉低" N. ^. ?1 Q& j6 M6 |. L( A
- HAL_Delay(20); //至少18ms* u( _% W- O _* J# `# L+ |# v( i
- DHT11_DQ_OUT_HIGH; //拉高
7 C- V5 W4 Q# Y" c& I - delay_us(30); //至少20~40us% J) C! C$ y8 p' R, g. F
- }5 B# X* R( _7 ]5 l7 f' b
- ) m* f' y* k) J/ ^! ^* W8 k; K ]
- uint8_t DHT11_Check(void){
% d# _ Y2 Y3 r) q8 N! v; S - uint8_t retry=0;) q& J u2 l* u- ^/ L
- DHT11_IO_IN(); 6 ]& l- J3 H: P1 q9 G) \6 G
- while (DHT11_DQ_IN&&retry<100){ //拉低40~80us7 t# O# J% s/ H$ m# t0 E" ]& e
- retry++;9 Q6 e9 {$ P# f |' }2 [1 A- i/ m7 B
- delay_us(1); X- j7 d8 J" {
- }; ' f, {5 I3 \1 I' V# r& N) V
- if(retry>=100)return 1;
9 ] ~/ H# g/ D - else retry=0;
& [5 z9 S0 } ~% H) x% u1 m - while (!DHT11_DQ_IN&&retry<100){ //拉高40~80us( x2 Y" d' x; z2 r$ W8 a, u
- retry++;! b# L+ |5 x8 i, d) h/ I
- delay_us(1);# R* p- K# w$ R- l% g! J" H* y$ G
- };
3 L% R4 i4 y/ }3 G0 o5 l! }7 V - if(retry>=100)return 1; 8 p4 y0 ?1 ^& x4 h$ r
- return 0; //检测到DHT11返回08 P% y, b' e" }/ i& L
- }) S, B" f6 e+ {$ X
- ) M( E8 O- m R
- uint8_t DHT11_Read_Bit(void){
' p8 ?; z1 i: I2 x% o4 S. u - uint8_t retry=0;9 a' t2 ^8 r" s2 E. H& ?/ ? F" F. D
- while(DHT11_DQ_IN&&retry<100){//等待变为低电平 w2 V Z' L" B8 f: l; A
- retry++;
' ?6 @$ A( r2 H' u' I$ Q3 X, m - delay_us(1);
. o3 a; L' p% G: o, _ - }
9 ^2 r! f/ |7 A* }: Q - retry=0;
3 h+ V5 p0 C/ I) }4 v4 e2 v2 F - while(!DHT11_DQ_IN&&retry<100){//等待变为高电平4 W- q" `# K5 c3 |
- retry++;
& P x. ^0 {) x; l% ] - delay_us(1);
4 S8 o. x( S- t k( O1 H - }
" \; x0 B" i* J M2 W- m8 }) T9 E - delay_us(40); //等待40us4 j: }) F5 T0 y d
- if(DHT11_DQ_IN)return 1;# f8 G3 @$ z+ D' M! Z5 a6 R( e
- else return 0;
: k; r8 w) Y! m" ~3 Q1 l - }
) Z5 S `3 l) n# a9 v3 |8 z3 D - ) I& h _1 G7 _
- uint8_t DHT11_Read_Byte(void){
& L- [2 |5 Y/ G7 w, K' q N+ h - uint8_t i,dat;6 g6 S: o/ K( q5 s( x5 J3 K
- dat=0;
7 F- G R: O6 Y - for (i=0;i<8;i++){
8 T3 e7 j9 f, i. Y2 F - dat<<=1; B, p- c" V/ T V
- dat|=DHT11_Read_Bit();
) r) g! a4 G9 S( E. ~ - }
8 S( ?- e |" _! g& `) P: s - return dat;
- A- n2 k, e5 t9 V5 d2 ]3 A - }
; Z) u9 k, z5 k8 ^ - 9 `+ A; N/ ]& N# e9 s' z/ F. C
- uint8_t DHT11_Read_Data(uint16_t *temp,uint16_t *humi){
3 N ^( N2 u: E6 d( ]7 I0 V4 |# o - uint8_t buf[5];
4 j1 W0 Q( @. e7 q7 f - uint8_t i;
5 k# I4 o9 ~2 p5 i4 R1 ^" J" | - DHT11_Rst();5 j( M2 x: z# ?- s. w" H
- if(DHT11_Check()==0){
! W8 I* Y) R R6 o! r - for(i=0;i<5;i++){' f D8 j) n* M
- buf[i]=DHT11_Read_Byte();; }8 S; [0 M5 [9 B5 g# u
- }
; q: w6 a: v6 ?5 _* x* q - if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){$ n+ d# S2 L) y' f+ K1 _4 _4 K* N
- *humi=(buf[0]<<8) + buf[1];& ^, W+ E' q( ^6 k' |, K: x9 H
- *temp=(buf[2]<<8) + buf[3];- K* j8 t, |$ @& |1 c. H
- }6 ]5 y4 t/ T( A6 y
- }else return 1;% p$ a: F; C, {# G
- return 0;
7 I" V. g* ?) b. P8 {' v - }
" A q9 g) d X f -
6 T5 g5 l2 X( J- k+ I - uint8_t DHT11_Init(void){6 q4 y0 z; }9 G$ L
- //PG11的初始化已经在cubemx中完成,可以忽略此段初始化代码
9 \* K- X, C& B6 }1 F# o* ?6 D - GPIO_InitTypeDef GPIO_Initure; 8 F+ D) x- q/ E1 b/ B. e; q
- __HAL_RCC_GPIOG_CLK_ENABLE(); " v& X1 d/ j. [0 y
- GPIO_Initure.Pin=GPIO_PIN_11; 8 S$ u4 \% G# S d
- GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;
. w6 T9 T( H/ `; |1 e% b - GPIO_Initure.Pull=GPIO_PULLUP;
9 F7 Q/ s2 x+ u4 F8 g - GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;
9 {8 F s5 D1 Y; Z% S - HAL_GPIO_Init(GPIOG,&GPIO_Initure);
! s5 M- m" U8 m - DHT11_Rst();
( h( u! Q. y* _; K, p' [ - return DHT11_Check();: [0 l! G+ \$ J% G/ v2 C" S! S& p5 C( {
- }
复制代码
3 {/ o; C! @. A- q' I0 T6 ~➡️ 在main.c文件下编写DHT11测试代码 - int main(void){- b8 {! @' G3 Z K4 K
- /* USER CODE BEGIN 1 */
2 t2 Z' w6 d; \9 @: @ - uint16_t temperature;
2 g6 b# N* D, m6 {/ R) q - uint16_t humidity;: S+ \- o0 T4 n# Q% U
- /* USER CODE END 1 */# Y! L% f5 [9 H7 V3 A, Y, j" f
- HAL_Init();: }7 T5 T; R5 G+ o- s
- SystemClock_Config();
+ H8 l' n- O' `) R9 k( L" H6 @9 n - MX_GPIO_Init();
% m! G" T* ~" z' D/ p* r4 T - MX_TIM7_Init();- |0 {; k# I8 f; R: r0 H9 U' H
- MX_USART1_UART_Init();, p: w: {9 W7 \
- /* USER CODE BEGIN 2 */
0 \+ p1 X$ ~/ z7 U1 _ - while(DHT11_Init()){0 ^6 J: t& m8 y. P( `; m
- printf("DHT11 Checked failed!!!\r\n");" H; u6 b9 X* m7 v
- HAL_Delay(500);! K/ p4 p( W9 | @& `) ?. b8 F
- }
8 K- {1 `7 Z) ]5 N, h - printf("DHT11 Checked Sucess!!!\r\n");
, z f8 w* Q. ]% \6 W- l - /* USER CODE END 2 */( w U" I$ s% ?8 q8 `3 v7 K1 t( K3 v
- while (1){' y. s: K% r" }0 k+ }( U
- DHT11_Read_Data(&temperature,&humidity);, i' h+ R) u$ D. q" v) L P$ v
- printf("DHT11 Temperature = %d.%d degree\r\n",temperature>>8,temperature&0xff);3 ~. S; l3 ^& o9 Q" [+ z
- printf("DHT11 Humidity = %d.%d%%\r\n",humidity>>8,humidity&0xff);
! g% t7 u/ S5 J, M j* D7 M6 O - HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);
. t& l# Q0 X y( t - HAL_Delay(500);
8 D) j" Y: k i0 ^8 n: J: E. }: t - }
/ l I- W+ [2 m, N) H - }
复制代码
! r$ A, O( A3 n& c4.下载验证 编译无误下载到开发板后,可以看到D1指示灯不断闪烁,串口不断打印出当前温湿度值。串口输出如下信息: DHT11 Checked Sucess!!! DHT11 Temperature = 28.20 degree DHT11 Humidity = 30.21% 转载自: 嵌入式攻城狮
; {/ k' Y: t# {9 ]如有侵权请联系删除& q2 _, k2 d; e9 a+ |
6 \7 q' ]0 @0 h, Q$ ^/ c8 k
# r. @2 J- `; {) K7 f0 L) | |