你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32CubeMX DHT11温湿度传感器经验分享

[复制链接]
攻城狮Melo 发布时间:2023-7-1 18:18
1.DHT11简介
DHT11是一款温湿度一体化的数字传感器,该传感器包括一个电阻式测湿元件和一个NTC测温元件,并与一个高性能8位单片机连接。通过单片机微处理器简单的电路连接就能够实时的采集湿度和温度。DHT11与STM32之间能采用简单的单总线进行通讯,仅需一个IO口。传感器内部温度和湿度数据40个bit的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。
DHT11采用单总线数据格式,即单个数据引脚端口完成输入输出双向传输。其数据包由5个字节(40Bit)组成。数据分小数和整数部分,一次完整的数据传输为40bit,高位先出。数据格式如下图示

6 F0 ~2 `+ ]7 s0 Y  _4 M( O. ?
微信图片_20230701181746.png
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
微信图片_20230701181742.png

% u* e% t9 n+ j; T2 v' t. s5 C
⏩ DHT11输出0时序
9 o4 e% o2 ^: @+ N$ m7 ]
微信图片_20230701181739.png

9 ?( h8 `( h5 a
⏩ DHT11输出1时序

6 S7 h/ a& T2 d
微信图片_20230701181736.png

5 A) v, Y+ d0 r+ l3 Z0 F! \

" @# z# n7 t; U1 r' A$ V
2.硬件设计
  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* g
3.软件设计
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
微信图片_20230701181727.png
% 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 s
3.2 MDK-ARM软件编程
( U4 |4 X3 t" g" X4 {
➡️ 在tim.c文件下实现微秒延时(us)函数
  1. void delay_us(uint16_t us){# d0 `: l. D; H& p5 }+ l/ k. Q
  2.   uint16_t differ = 0xffff-us-5;  j# }% W3 x- `. _8 y) |
  3.   //设定TIM7计数器起始值                                6 }3 @$ K- s8 k' V5 w* ]5 A$ T/ B% }
  4.   __HAL_TIM_SET_COUNTER(&htim7,differ);
    . D$ v8 x1 u5 {* B/ o9 `6 L
  5.   //启动定时器       
    # p. L: e5 G: ]$ G! M+ P
  6.   HAL_TIM_Base_Start(&htim7);                        / U% T& K: \6 R, M, e! T% s2 b
  7.         + D  w% w) s4 _: d2 @! w/ J; j( w
  8.   while(differ < 0xffff-5){        //判断
    , @8 L0 {0 M1 p1 x6 F
  9.     //查询计数器的计数值: U+ ]/ I0 o' p. Q1 {
  10.     differ = __HAL_TIM_GET_COUNTER(&htim7);                $ k/ T& ^/ V9 i# z
  11.   }6 }" J% b* R# V8 l4 Y
  12.   HAL_TIM_Base_Stop(&htim7);
    0 k4 d: v- n4 n2 z1 p/ u! m/ d) F0 c
  13. }
复制代码
9 ~5 k: p) B' s. J6 {
➡️ 创建DHT11温湿度传感器驱动文件DHT11.c 和相关头文件DHT11.h
  1. void DHT11_IO_IN(void){  //IO口方向设置为输入  I5 `! k7 ^8 r( |1 i
  2.   GPIO_InitTypeDef GPIO_InitStructure;
    ) [* q& @7 e6 Q5 ]5 W
  3.   GPIO_InitStructure.Pin = GPIO_PIN_11;
    ( T' H7 w& H) o- @- y' ^
  4.   GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
    & Z& m8 U. g! w7 \  H
  5.   HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);" S* m$ l$ D" X* W9 s
  6. }
    " v8 m& H4 [) T) Z- F3 W
  7. 5 E! V- {( R( j( Y( x2 r
  8. void DHT11_IO_OUT(void){  //IO口方向设置为输出
    % ^; E+ u; K6 y
  9.   GPIO_InitTypeDef GPIO_InitStructure;
    # k5 t9 E  e8 F  r
  10.   GPIO_InitStructure.Pin = GPIO_PIN_11;% B% q# _0 Z8 F, C& \; t- g8 x
  11.   GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    / `- U( |8 M) U& B" T4 l# ]0 l
  12.   GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;; x' `. M+ W8 X: i/ @+ @0 ~$ L
  13.   HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);
    + `9 R2 x6 l% q/ Z. E9 y( I; h8 H
  14. }: Z: f' s6 Z; e
  15. 7 Q' v$ e! v  \$ x
  16. void DHT11_Rst(void){                 / s9 Y  o4 p& \" t/ c
  17.   DHT11_IO_OUT();         //设置为输出2 K; X/ a" N: @
  18.   DHT11_DQ_OUT_LOW;         //拉低" N. ^. ?1 Q& j6 M6 |. L( A
  19.   HAL_Delay(20);            //至少18ms* u( _% W- O  _* J# `# L+ |# v( i
  20.   DHT11_DQ_OUT_HIGH;         //拉高
    7 C- V5 W4 Q# Y" c& I
  21.   delay_us(30);             //至少20~40us% J) C! C$ y8 p' R, g. F
  22. }5 B# X* R( _7 ]5 l7 f' b
  23. ) m* f' y* k) J/ ^! ^* W8 k; K  ]
  24. uint8_t DHT11_Check(void){   
    % d# _  Y2 Y3 r) q8 N! v; S
  25.   uint8_t retry=0;) q& J  u2 l* u- ^/ L
  26.   DHT11_IO_IN();      6 ]& l- J3 H: P1 q9 G) \6 G
  27.   while (DHT11_DQ_IN&&retry<100){ //拉低40~80us7 t# O# J% s/ H$ m# t0 E" ]& e
  28.     retry++;9 Q6 e9 {$ P# f  |' }2 [1 A- i/ m7 B
  29.     delay_us(1);  X- j7 d8 J" {
  30.   };         ' f, {5 I3 \1 I' V# r& N) V
  31.   if(retry>=100)return 1;
    9 ]  ~/ H# g/ D
  32.   else retry=0;
    & [5 z9 S0 }  ~% H) x% u1 m
  33.   while (!DHT11_DQ_IN&&retry<100){ //拉高40~80us( x2 Y" d' x; z2 r$ W8 a, u
  34.     retry++;! b# L+ |5 x8 i, d) h/ I
  35.     delay_us(1);# R* p- K# w$ R- l% g! J" H* y$ G
  36.   };
    3 L% R4 i4 y/ }3 G0 o5 l! }7 V
  37.   if(retry>=100)return 1;            8 p4 y0 ?1 ^& x4 h$ r
  38.   return 0;        //检测到DHT11返回08 P% y, b' e" }/ i& L
  39. }) S, B" f6 e+ {$ X
  40. ) M( E8 O- m  R
  41. uint8_t DHT11_Read_Bit(void){
    ' p8 ?; z1 i: I2 x% o4 S. u
  42.   uint8_t retry=0;9 a' t2 ^8 r" s2 E. H& ?/ ?  F" F. D
  43.   while(DHT11_DQ_IN&&retry<100){//等待变为低电平  w2 V  Z' L" B8 f: l; A
  44.     retry++;
    ' ?6 @$ A( r2 H' u' I$ Q3 X, m
  45.     delay_us(1);
    . o3 a; L' p% G: o, _
  46.   }
    9 ^2 r! f/ |7 A* }: Q
  47.   retry=0;
    3 h+ V5 p0 C/ I) }4 v4 e2 v2 F
  48.   while(!DHT11_DQ_IN&&retry<100){//等待变为高电平4 W- q" `# K5 c3 |
  49.     retry++;
    & P  x. ^0 {) x; l% ]
  50.     delay_us(1);
    4 S8 o. x( S- t  k( O1 H
  51.   }
    " \; x0 B" i* J  M2 W- m8 }) T9 E
  52.   delay_us(40);        //等待40us4 j: }) F5 T0 y  d
  53.   if(DHT11_DQ_IN)return 1;# f8 G3 @$ z+ D' M! Z5 a6 R( e
  54.   else return 0;                  
    : k; r8 w) Y! m" ~3 Q1 l
  55. }
    ) Z5 S  `3 l) n# a9 v3 |8 z3 D
  56. ) I& h  _1 G7 _
  57. uint8_t DHT11_Read_Byte(void){        
    & L- [2 |5 Y/ G7 w, K' q  N+ h
  58.   uint8_t i,dat;6 g6 S: o/ K( q5 s( x5 J3 K
  59.   dat=0;
    7 F- G  R: O6 Y
  60.   for (i=0;i<8;i++){
    8 T3 e7 j9 f, i. Y2 F
  61.     dat<<=1;   B, p- c" V/ T  V
  62.     dat|=DHT11_Read_Bit();
    ) r) g! a4 G9 S( E. ~
  63.   }                                                    
    8 S( ?- e  |" _! g& `) P: s
  64.   return dat;
    - A- n2 k, e5 t9 V5 d2 ]3 A
  65. }
    ; Z) u9 k, z5 k8 ^
  66. 9 `+ A; N/ ]& N# e9 s' z/ F. C
  67. uint8_t DHT11_Read_Data(uint16_t *temp,uint16_t *humi){        
    3 N  ^( N2 u: E6 d( ]7 I0 V4 |# o
  68.   uint8_t buf[5];
    4 j1 W0 Q( @. e7 q7 f
  69.   uint8_t i;
    5 k# I4 o9 ~2 p5 i4 R1 ^" J" |
  70.   DHT11_Rst();5 j( M2 x: z# ?- s. w" H
  71.   if(DHT11_Check()==0){
    ! W8 I* Y) R  R6 o! r
  72.     for(i=0;i<5;i++){' f  D8 j) n* M
  73.       buf[i]=DHT11_Read_Byte();; }8 S; [0 M5 [9 B5 g# u
  74.     }
    ; q: w6 a: v6 ?5 _* x* q
  75.     if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){$ n+ d# S2 L) y' f+ K1 _4 _4 K* N
  76.       *humi=(buf[0]<<8) + buf[1];& ^, W+ E' q( ^6 k' |, K: x9 H
  77.       *temp=(buf[2]<<8) + buf[3];- K* j8 t, |$ @& |1 c. H
  78.     }6 ]5 y4 t/ T( A6 y
  79.   }else return 1;% p$ a: F; C, {# G
  80.   return 0;            
    7 I" V. g* ?) b. P8 {' v
  81. }
    " A  q9 g) d  X  f
  82.            
    6 T5 g5 l2 X( J- k+ I
  83. uint8_t DHT11_Init(void){6 q4 y0 z; }9 G$ L
  84.   //PG11的初始化已经在cubemx中完成,可以忽略此段初始化代码
    9 \* K- X, C& B6 }1 F# o* ?6 D
  85.   GPIO_InitTypeDef GPIO_Initure;        8 F+ D) x- q/ E1 b/ B. e; q
  86.   __HAL_RCC_GPIOG_CLK_ENABLE();                        " v& X1 d/ j. [0 y
  87.   GPIO_Initure.Pin=GPIO_PIN_11;           8 S$ u4 \% G# S  d
  88.   GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  
    . w6 T9 T( H/ `; |1 e% b
  89.   GPIO_Initure.Pull=GPIO_PULLUP;         
    9 F7 Q/ s2 x+ u4 F8 g
  90.   GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;
    9 {8 F  s5 D1 Y; Z% S
  91.   HAL_GPIO_Init(GPIOG,&GPIO_Initure);   
    ! s5 M- m" U8 m
  92.   DHT11_Rst();
    ( h( u! Q. y* _; K, p' [
  93.   return DHT11_Check();: [0 l! G+ \$ J% G/ v2 C" S! S& p5 C( {
  94. }
复制代码

3 {/ o; C! @. A- q' I0 T6 ~
➡️ 在main.c文件下编写DHT11测试代码
  1. int main(void){- b8 {! @' G3 Z  K4 K
  2.   /* USER CODE BEGIN 1 */
    2 t2 Z' w6 d; \9 @: @
  3.   uint16_t temperature;
    2 g6 b# N* D, m6 {/ R) q
  4.   uint16_t humidity;: S+ \- o0 T4 n# Q% U
  5.   /* USER CODE END 1 */# Y! L% f5 [9 H7 V3 A, Y, j" f
  6.   HAL_Init();: }7 T5 T; R5 G+ o- s
  7.   SystemClock_Config();
    + H8 l' n- O' `) R9 k( L" H6 @9 n
  8.   MX_GPIO_Init();
    % m! G" T* ~" z' D/ p* r4 T
  9.   MX_TIM7_Init();- |0 {; k# I8 f; R: r0 H9 U' H
  10.   MX_USART1_UART_Init();, p: w: {9 W7 \
  11.   /* USER CODE BEGIN 2 */
    0 \+ p1 X$ ~/ z7 U1 _
  12.   while(DHT11_Init()){0 ^6 J: t& m8 y. P( `; m
  13.     printf("DHT11 Checked failed!!!\r\n");" H; u6 b9 X* m7 v
  14.     HAL_Delay(500);! K/ p4 p( W9 |  @& `) ?. b8 F
  15.   }
    8 K- {1 `7 Z) ]5 N, h
  16.   printf("DHT11 Checked Sucess!!!\r\n");
    , z  f8 w* Q. ]% \6 W- l
  17.   /* USER CODE END 2 */( w  U" I$ s% ?8 q8 `3 v7 K1 t( K3 v
  18.   while (1){' y. s: K% r" }0 k+ }( U
  19.     DHT11_Read_Data(&temperature,&humidity);, i' h+ R) u$ D. q" v) L  P$ v
  20.     printf("DHT11 Temperature = %d.%d degree\r\n",temperature>>8,temperature&0xff);3 ~. S; l3 ^& o9 Q" [+ z
  21.     printf("DHT11 Humidity = %d.%d%%\r\n",humidity>>8,humidity&0xff);               
    ! g% t7 u/ S5 J, M  j* D7 M6 O
  22.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);
    . t& l# Q0 X  y( t
  23.     HAL_Delay(500);
    8 D) j" Y: k  i0 ^8 n: J: E. }: t
  24.   }
    / l  I- W+ [2 m, N) H
  25. }
复制代码

! r$ A, O( A3 n& c
4.下载验证
编译无误下载到开发板后,可以看到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) |
赞 收藏 评论0 发布时间:2023-7-1 18:18

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版