请选择 进入手机版 | 继续访问电脑版

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

STM32F103VET6实现采集温湿度数据

[复制链接]
STMCU小助手 发布时间:2023-2-5 18:50
前言" V9 ?7 [( @$ s0 R
了解DHT11温湿度传感器相关知识,进行DHT11传感器的开发及数据获取,并通过串口调试助手查看" ~/ ^, w) R: G7 P
# E( c6 h, D  l9 I, }
一、温湿度传感器相关知识
8 q7 Y3 r( y. F  `
1. DHT11简介
* H: O+ a+ _2 ]; B0 t* f" zDHT11温湿度传感器是一种比较便宜的常见的温湿度传感器,它的内部由两个元件构成,一个是电阻式的感湿元件用来检测环境湿度,另一个是NTC测温元件来测量温度,在测得数据后,两个元件会将数据传送给内部一个集成的8位的处理器来对数据进行处理,并将它们转换为数字量,这些数据可以通过串口传送给主机。DHT11温湿度传感器有四个管脚,只有一条是数据线接口,所以在传输数据时仅需要1个I/O就能同时传输测得的温度以及湿度,在进行程序编写时更加简洁方便。因为DHT11集成度较好,体积比较小,所以消耗也很小,抗干扰能力更强,稳定性较好,不易受到外界干扰。( ~: c( h1 H# B6 x
( s; n; Q5 q1 g- s
Pin1 VDD 供电 3-5.5V DC3 s3 o; l. Z9 a# ^  y1 e+ f
Pin2 DATA 串行数据,单总线  n& Z6 y  b% h2 t
Pin3 NC 空脚,悬空. N# q1 R# D2 ?8 }
Pin4 GND 接地,电源负极* O! G4 r  G5 r" p# p. Y
1 n) o2 A, O% t! x$ Y
DHT11集成度很高,封装的很简洁,只有四个管脚,所以连接也是相对比较方便。DHT11管脚Pin1接一个3-5.5V的直流电源的正极,管脚Pin2为数据端,主要用于传输数据,但是在接线时需要加一个5KΩ的上拉电阻连接到主机MCU上,用来保证数据传输的稳定性,同时还要注意这个5KΩ是在管脚Pin2与主机之间的接线小于20m时才有用,在大于20m时就需要根据实际情况来确定需要加多大的上拉电阻来保持稳定性。管脚Pin3不起什么作用,只需要将其悬空不接线即可,管脚Pin4接地。0 W3 w; k0 D( V- W- ?8 b

8 `, f( G1 j' |+ f- n, t1 L8 b
1 n0 O# t+ `# T2 E2 s
2.数据格式
! Y; O- J9 [3 w6 _8 sDHT11和DS18B20不同,DHT11不需要配置,可以直接读取数据,一次完整的数据传输为40bit,先传输高字节的数据再传输低字节的数据,也就是低位后出,高位先出模式。* `- [2 S$ S0 B5 j
数据格式: 8bit湿度整数数据 + 8bit湿度小数数据. a, ]0 c8 ?0 ?  e) ^
+8bit温度整数数据 + 8bit温度小数数据& _. ~' j( |; n8 W8 e
+8bit校验和
( w: X! v! T5 Q& U数据传送正确时校验和数据等于. Q/ d7 B; }9 P
8bit湿度整数数据 + 8bit湿度小数数据- \1 ^# i; U4 Y( m/ r9 a- U
+8bit温度整数数据 + 8bit温度小数数据& m: Z4 b, ^- g' H6 b. f
所得结果的末8位。1 X6 q3 }9 n+ Q( K5 c

# n$ f2 v) A; ~* @8 h
  v+ V  y+ c; w3 W' `
3.数据传输. P6 D  @. B+ d; B/ {
数据线一开始处于高电平状态,用户MCU将总线电平拉低,表示用户要开始获取数据,然后将电平拉高并延时等待一段时间,等待DHT11回复,如果DHT11将总线拉低,表示已经收到主机信号,并响应主机信号,准备输出,然后将总线电平拉高,并延时一段时间,表示准备传输40bit的数据。然后将数据总线拉低一段时间开始传输数据,主要是进行2进制数据传输,传输0和1,并用不同的拉高电平延时时间来表示数据0和1。用户可以选择读取湿度还是温度,整数还是小数。并且数据传输是需要DHT11收到主机MCU发送的开始信号,才会开始采集数据传输数据,而且此时DHT11会转到低速模式。6 B) V9 r+ @1 d9 n( k7 Q
- L' x6 w. ]  O
1d4a7e41310f44198a2a3914b9f59db3.png , d. D, e, }: i/ v, K; L
8 u. i% ^$ s. p+ ]
总线在空闲时因为上拉电阻会处于高电平状态,主机用户MCU会发送信号将电平拉低至少18us,太短DHT11可能会检测不到主机的起始信号。之后主机会再将电平拉高20-40us,DHT11识别到后,会将电平拉低80us,表示DHT11已经接收到主机发送的开始信号,之后再将总线切换到输入模式,然后DHT11会再将电平拉高80us表示竹北开始传输数据。之后会再将电平拉低,然后开始传输数据。
2 F, Q3 h1 l, q
$ T) H, m5 k. K- F' i, G当接收到主机的开始信号后,DHT11会将总线拉低80us来发送响应信号,表示已经接收到,然后会将总线拉高80us,并准备发送数据,每一位的数据都以50us的低电平间隙开始,就是每两个数据之间都有一个50us的低电平信号来表示一位数据传输完成。DHT11用电平拉高延时的时间来表示数据为位0还是1。通常用拉高26-28us来表示数据‘0’,用拉高70us来表示数据‘1’。当最后一位数据传输完成后,DHT11会将总线拉低50us,随后总线又会因为上拉电阻将总线拉高,并处于空闲状态。
7 c1 ^- f4 P4 V4 g# e; ]" O
" Q( D6 R5 x: B3 a! U( ]DHT11读取数据“0”时序图
) r6 ?: E; F+ l: k5 p
$ d" e' ]; l- q$ }' [% ?( ?; K
ea92ef3f20334c68aa75e8b83aefa06f.png # c3 S, t9 z( i4 ^- H
& h& k3 b" b! Y( o: l5 j; P2 W
DHT11读数据“1”时序图. J" t* Q" G9 V6 j+ x' |
. ?% z0 g& J4 r9 S* h$ r* o# A1 R
d7d734cf63a942ecbe48dc4f2ae1fc4b.png ( f+ w4 x8 S% Q6 Y+ @. {
+ Z' ]2 E8 _0 W; P
" v/ `+ D% {/ m2 y
二、程序实现
3 c/ }2 X. }% s3 u- b2 X, m. M7 t+ B1.dht11.h1 A, }) b+ U& y9 u/ y/ M6 t* r9 P* h; b
DHT11的程序实现主要是根据它的读写时序来实现的,因此在进行程序的编写时要根据它的读写时序进行模拟,实现单片机与DHT11之间的数据通信。
: c# d" W: M% D1 B* Z4 L  v, M7 L- ^1 I" h

, L, z% S6 q5 O代码如下(示例):
. u0 f3 }2 H; s8 l( P
  1. #ifndef __DHT11_H- J& H( ]" h7 {5 F+ x3 E- Z4 }3 ]. {
  2. #define __DHT11_H1 u1 ?' O$ V- {/ O* P+ N
  3. 9 q5 s9 M/ ~! J7 U: }
  4. #include "stm32f10x.h"
    / T9 w2 p- k) c6 s! M0 |% s

  5. , U& C' f9 p  m1 E4 a8 }
  6. typedef struct9 i% f6 R  u$ N1 B* }
  7. {9 q/ ]) O. ]% S& d/ c. E( r* L
  8.         uint8_t  humi_int;                //湿度的整数部分0 X* I: \" k4 ?
  9.         uint8_t  humi_deci;                 //湿度的小数部分& U4 F3 O3 c( n0 Q! e
  10.         uint8_t  temp_int;                 //温度的整数部分8 X# k0 h+ |  ?' h/ E% U3 N' P! T
  11.         uint8_t  temp_deci;                 //温度的小数部分
    " @/ u1 f( B" N( ~) \1 H" {
  12.         uint8_t  check_sum;                 //校验和9 o3 `1 v8 L) \- i, c$ `0 o
  13.                                  5 u$ `, {1 \% t  h0 M: I9 L, \
  14. } DHT11_Data_TypeDef;
    4 R( N9 g4 u) g0 \& q
  15. 8 }2 s! V, j: D2 E

  16. 3 @% _6 J9 P0 L4 x( \

  17. ) g, a  A5 X; b! `
  18. /************************** DHT11 连接引脚定义********************************/* d5 N: b2 E' n) T
  19. #define      DHT11_Dout_SCK_APBxClock_FUN              RCC_APB2PeriphClockCmd( W1 X0 J1 r! D; o9 c! p# W
  20. #define      DHT11_Dout_GPIO_CLK                       RCC_APB2Periph_GPIOE
    6 k6 t+ ~6 z7 K# X+ q1 e
  21. 1 B. o: G) S& T" k
  22. #define      DHT11_Dout_GPIO_PORT                      GPIOE  r4 n4 ?7 {1 y" @
  23. #define      DHT11_Dout_GPIO_PIN                       GPIO_Pin_6. ^' ?! [" n( c' E7 d7 M; G7 ]
  24. 6 J; X4 G$ H" S' b  Q' ]( R

  25. ' A8 |( V+ i: ^( W( A5 y

  26. - X# y/ w' ]+ \4 x# V, m5 Z0 h9 \6 _
  27. /************************** DHT11 函数宏定义********************************/
    " ~6 r# U, |# p7 t6 l# F
  28. #define      DHT11_Dout_0                                    GPIO_ResetBits ( DHT11_Dout_GPIO_PORT, DHT11_Dout_GPIO_PIN )
    - P, c( B& V+ e$ m/ g+ h
  29. #define      DHT11_Dout_1                                    GPIO_SetBits ( DHT11_Dout_GPIO_PORT, DHT11_Dout_GPIO_PIN ) 9 q% Y1 s' {, @" m

  30. ) A& s  z1 @! Q% l1 p, U
  31. #define      DHT11_Dout_IN()                                  GPIO_ReadInputDataBit ( DHT11_Dout_GPIO_PORT, DHT11_Dout_GPIO_PIN )
    2 Y- e! ?, c* Y' U" u; t- N
  32. 3 n8 S! t9 N6 i6 j" K
  33. / c0 q0 T/ G8 V' L/ Q2 j( l
  34.   Y$ E0 o. k8 L! m% \
  35. /************************** DHT11 函数声明 ********************************/( R: g3 ~6 P/ r/ W% ~/ j- ?
  36. void                     DHT11_Init                      ( void );
    6 ~; \, r+ ~0 ^
  37. uint8_t                  DHT11_Read_TempAndHumidity      ( DHT11_Data_TypeDef * DHT11_Data );
    6 K9 Y/ F% {- U" }2 [, W7 z! S
  38. / x: G+ E( e& L: x0 j# k
  39. #endif, O/ D- P! U% X+ d0 l2 B# [
复制代码
, _$ ?* _% ]7 V) R4 `' K
DHT11用到的数据总线是PE6,接线时,DHT11数据线接到PE6,以及我们需要用到的函数的声明:& Y2 r2 V( x9 N) e: T3 X& l+ |. s
Void DHT11_Init(void)为DHT11的初始化函数;
* }8 F4 Q& p* L' |7 L$ Muint8_t DHT11_Read_TempAndHumidity ( DHT11_Data_TypeDef * DHT11_Data )为DHT11的数据读取函数,这个函数会将读取到的数据赋值给DHT11_Data结构体里的变量,然后还会有一个返回值判断是否读取成功;( T2 ]9 d. p# B# S2 `3 T

1 n8 _5 r7 j4 S- c' b2.dht11.c, u5 ?6 {! t* d1 c% B. z- w
代码如下(示例):3 T' h; w0 k& j! Z$ e5 ~
  1. #include "dht11.h"
    1 D; t$ r% a$ @8 [! |/ U
  2. #include "delay.h"$ M5 [* R1 S1 F$ z/ ]: y7 @! A
  3. 3 z' r" V* V+ d8 `
  4. static void                           DHT11_GPIO_Config                       ( void );+ ~4 C3 c- K5 c% y' S! x! [  ]
  5. static void                           DHT11_Mode_IPU                          ( void );
    ) {, o/ M4 D* |. e' Z
  6. static void                           DHT11_Mode_Out_PP                       ( void );: h" i! z+ c4 [$ R. p
  7. static uint8_t                        DHT11_ReadByte                          ( void );! m- H0 _7 ]2 i# u6 p
  8. % k4 ^. A3 f1 l) T

  9. + R! o' Q" x. y6 v
  10. /**& e$ ~! {- X8 m. |9 k4 k
  11.   * @brief  DHT11 初始化函数0 u: a' o; u1 m% {; v
  12.   * @param  无
    5 @5 V2 T/ O6 U8 [. Y
  13.   * @retval 无+ m$ {3 @2 Z) ^: y
  14.   */
    6 [5 y! l  @, ?6 f& {
  15. void DHT11_Init ( void )
    8 i# i8 G8 v6 R! \4 R- @8 N% B& B
  16. {
    7 k* L2 X# ^, C0 F7 w8 G0 V7 q
  17.         DHT11_GPIO_Config ();
    1 f2 Y' C; t/ i1 B: `
  18.         $ m( }  |3 Y: H# V
  19.         DHT11_Dout_1;               // 拉高GPIOB10: k; p8 p8 a% d3 o, q1 a4 D8 o2 x3 O
  20. }2 h" t( e$ c: Z4 z& k; R
  21. $ n: b2 y; l# ^/ s! j; v+ _
  22. /*6 v3 [. Z  N) [1 A' [7 i2 q1 h
  23. * 函数名:DHT11_GPIO_Config0 |6 p9 x. z& ?# d8 R: S7 G
  24. * 描述  :配置DHT11用到的I/O口
    : h$ v+ |% h3 d( K$ h
  25. * 输入  :无
    # v7 `) t3 |9 @0 A/ y. Z% I* ?
  26. * 输出  :无' ^( O. `/ g- l* S, n) B. v3 J0 |
  27. */
    . C7 V- v, ?  b/ Z# ?. n3 o
  28. static void DHT11_GPIO_Config ( void )
    $ X5 e4 C6 m! C: k& R* i
  29. {               
    8 b1 ~9 q1 V7 P4 F& |8 m
  30.         /*定义一个GPIO_InitTypeDef类型的结构体*/
    ( A0 N7 ?* W3 @# F4 z$ V! `: C! i4 x
  31.         GPIO_InitTypeDef GPIO_InitStructure; 4 N, l1 Z- Q+ b1 x' x0 F

  32. . u. z% g: S' ~9 c% j* k8 `
  33.        
    0 f+ x( r0 o2 A1 r9 S# Q; f* }
  34.         /*开启DHT11_Dout_GPIO_PORT的外设时钟*/: Z% M& p- L& C+ M8 F8 M
  35.   DHT11_Dout_SCK_APBxClock_FUN ( DHT11_Dout_GPIO_CLK, ENABLE );        $ N+ K$ h9 s& x+ x8 g# [) W
  36. 9 j2 j% w5 y" `$ Y2 u4 U: K
  37.         /*选择要控制的DHT11_Dout_GPIO_PORT引脚*/                                                                                                                          
    8 v* T7 d  ~) U. ^4 f
  38.           GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;       
    0 l6 m& {2 L" [! B
  39. % F% ]6 w  @: k
  40.         /*设置引脚模式为通用推挽输出*/. G: ]/ u. O$ D: r7 r
  41.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   3 S( \7 \6 c( C  l3 v

  42. % v6 [9 B: s0 W0 ?0 k8 T, L1 u- \9 g
  43.         /*设置引脚速率为50MHz */   8 G1 R# _2 z% ^% n$ r
  44.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    . w1 W* `% z+ [4 {. w( f

  45. ; k+ Y5 q6 k0 [" _. d
  46.         /*调用库函数,初始化DHT11_Dout_GPIO_PORT*/
    % G5 O9 ~! X$ p+ \; D3 X: U; r5 \- d1 R
  47.           GPIO_Init ( DHT11_Dout_GPIO_PORT, &GPIO_InitStructure );                  & X- ^8 F8 \  s7 P" f" Z+ X
  48.        
    / \; [0 Y- m+ X5 O5 g" M
  49. }: {' E! h7 [7 j# i7 Q- L1 b
  50. % u8 Q+ d* [0 h' e! I* H8 w
  51. /*
    ' j3 X; G! U3 T9 H
  52. * 函数名:DHT11_Mode_IPU. J% `& B- h% l* t9 F2 `
  53. * 描述  :使DHT11-DATA引脚变为上拉输入模式- E5 `5 p! o" d! A$ M* X7 N
  54. * 输入  :无. r/ z" D  [2 J  x2 `8 ?2 N+ m: e
  55. * 输出  :无
    0 F; g( h( M/ B
  56. */
    ; D7 N' M. w) S6 O
  57. static void DHT11_Mode_IPU(void)
    # U) @4 f3 V% M& p2 m
  58. {1 {" b2 R! L. M, a  t
  59.           GPIO_InitTypeDef GPIO_InitStructure;
    . X& {4 \1 c0 x! ?" b4 O
  60. + U8 Q7 k& F; b* P4 [, @! X7 \
  61.                   /*选择要控制的DHT11_Dout_GPIO_PORT引脚*/        6 {  T& R2 C" R: w7 v- j4 u. _" ^0 r
  62.           GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;; R5 l# J: x5 z& U
  63. * ?8 q( H9 M8 {9 ~
  64.            /*设置引脚模式为浮空输入模式*/ " k& Q& b) M1 X; r1 t
  65.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;
    : k% Z, a' M, b' q4 {
  66. % A/ ~. i1 R  v, f4 D4 C
  67.           /*调用库函数,初始化DHT11_Dout_GPIO_PORT*/( b4 n8 z5 G' d* y; j/ }5 z/ w
  68.           GPIO_Init(DHT11_Dout_GPIO_PORT, &GPIO_InitStructure);         : A. t! q, C+ f5 b$ A
  69.         % {, i" S! U5 {4 K9 W& f5 B
  70. }
    . h- B6 w% h/ ]
  71. ) X/ |$ H  T' J  l
  72. /*
    ! g5 G. K5 ]1 I4 `, }( X. _
  73. * 函数名:DHT11_Mode_Out_PP" g! q/ i. D$ |" @+ H7 s- A
  74. * 描述  :使DHT11-DATA引脚变为推挽输出模式
    ( v# [3 J1 {  t" a4 p8 M3 ^5 Z& [
  75. * 输入  :无
    2 t. j) N/ y: [% Q) c
  76. * 输出  :无
    1 i: I* Z, L5 I/ {3 h1 h
  77. */3 P0 Q1 p% K/ s5 I3 W2 l
  78. static void DHT11_Mode_Out_PP(void)0 w2 P1 f3 V# l' x0 D  K, F; U. q
  79. {
    $ J- r% J4 [2 o. F, i7 `0 Y
  80.         GPIO_InitTypeDef GPIO_InitStructure;- K2 {# G- \  z6 I
  81. 0 ?2 v) k5 `* ^/ ~3 o5 L# f. a
  82.                  /*选择要控制的DHT11_Dout_GPIO_PORT引脚*/                                                                                                                          
    0 J  t/ s; J! L6 |9 `- }
  83.           GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;        " }* G4 e9 p1 o7 P

  84. 0 f8 _9 `, c& x9 N7 u$ u% ^9 Q$ @
  85.         /*设置引脚模式为通用推挽输出*/. B' N+ P( O7 M4 p  s5 h
  86.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   & V' n) @9 ]) c8 [  c; Z* X+ T

  87. ; u4 _- U6 f6 f  \1 h
  88.         /*设置引脚速率为50MHz */   , l& v% f# M+ n9 i
  89.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    1 l* X* A$ R) M$ `" W

  90. / A1 e8 N  b. ]$ K, m* e( E( m
  91.         /*调用库函数,初始化DHT11_Dout_GPIO_PORT*/
    , c1 v* r+ l7 f
  92.           GPIO_Init(DHT11_Dout_GPIO_PORT, &GPIO_InitStructure);                  % {3 O4 S$ C0 F3 x
  93.        
    + Q; D& f( u2 t4 y! p$ t
  94. }
    7 j- h+ @- }" Y; G  l
  95. - o& e1 t4 }+ X# S1 s; @
  96. /* ) B, c* i8 B& M
  97. * 从DHT11读取一个字节,MSB先行1 s1 D0 P9 @, J$ j+ M' _% ~
  98. */8 p/ ^) `7 T6 M! }0 P2 ^
  99. static uint8_t DHT11_ReadByte ( void )
    9 ]/ Z! t& e- A
  100. {8 P5 T+ [' Z: ]* N3 r
  101.         uint8_t i, temp=0;
    6 V7 E1 @  m# F  X" `% k" c
  102.           [, D( s/ a& C, s4 K

  103. 4 m) J5 X8 R: b4 C3 `9 Q
  104.         for(i=0;i<8;i++)    $ ?4 B/ \) T7 W, d( x# S8 N
  105.         {         
    : m2 A! {  a- P" m# |3 g# m. z+ H
  106.                 /*每bit以50us低电平标置开始,轮询直到从机发出 的50us 低电平 结束*/  
    4 S, o. C/ O# M' g/ p4 r5 p
  107.                 while(DHT11_Dout_IN()==Bit_RESET);
    # t/ ]; h: ]( l& \3 ]! W4 l' I& m

  108. ) U" X* R, D$ K1 A2 P5 k- t
  109.                 /*DHT11 以26~28us的高电平表示“0”,以70us高电平表示“1”,% C$ `. f9 I" f8 j7 l* p
  110.                  *通过检测 x us后的电平即可区别这两个状 ,x 即下面的延时 9 S3 o2 W$ n! f
  111.                  */  ^  c; T+ N( m$ |' U- }8 F
  112.                 delay_us(40); //延时x us 这个延时需要大于数据0持续的时间即可                     ) v( Z7 t2 b8 q
  113. + r8 t$ c% X  b# U0 R5 q
  114.                 if(DHT11_Dout_IN()==Bit_SET)/* x us后仍为高电平表示数据“1” */
    7 t, Z: K1 L7 w: y
  115.                 {6 c+ d4 G5 @5 a
  116.                         /* 等待数据1的高电平结束 */
    " h% g9 ~# L9 I7 H* y3 @/ A
  117.                         while(DHT11_Dout_IN()==Bit_SET);6 y  T, R; A* W7 ~

  118. ( Q+ R/ U& v7 c: ~' G
  119.                         temp|=(uint8_t)(0x01<<(7-i));  //把第7-i位置1,MSB先行 , {+ @% U9 |. A9 T# p, {
  120.                 }
    ) j/ Y; e6 K7 Q7 K  k4 q
  121.                 else         // x us后为低电平表示数据“0”
    ! T; @. b9 L: h! Q7 w
  122.                 {                          
    & b! @- r, `7 N' H
  123.                         temp&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0,MSB先行
    / e7 z5 W- C1 R) A' v
  124.                 }4 n4 k7 |8 @& f
  125.         }6 @7 [" s* W& {. g! c) h$ u& p
  126.        
    9 e  m# t/ J0 }% N9 @
  127.         return temp;
    $ ?4 ^1 I/ o3 A' g, Z  N1 J1 x9 V
  128.        
    * W3 t! s4 t: q" N7 x
  129. }
    ' l" U$ U' A( s- ~

  130. / ]1 }* V* D2 K) Q

  131. 0 t7 s7 x$ A9 Z! b2 ?0 R
  132. /*
    ( b+ d9 \2 z) h! [2 V) Y
  133. * 一次完整的数据传输为40bit,高位先出% S$ z9 K* a% {9 z# e1 N& p, X
  134. * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和 / ^% N) K- ^( M! {, C  B
  135. */
    ' O; |4 u, a" ~8 f
  136. uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)
    : ]; Z& N% r! o
  137. {  
    - A' [# g, u+ |+ x  S) @- t
  138.         /*输出模式*/
    : m6 O3 X9 [# G# b6 X6 t
  139.         DHT11_Mode_Out_PP();
    5 _- y' p' E- r/ [% s
  140.         /*主机拉低*/
    9 J5 }6 h- a# Q0 X0 r5 g% B9 x
  141.         DHT11_Dout_0;" `, h3 _  A  g: H0 D6 U
  142.         /*延时18ms*/3 e# `8 o3 g. z) P3 K( z
  143.         delay_ms(18);
    & [) g5 g, P- L5 w

  144. . _5 |0 I1 `+ T4 K' [  A3 l
  145.         /*总线拉高 主机延时30us*/
    / e: i1 P& e/ P' a
  146.         DHT11_Dout_1; 0 C0 e" ]5 E: W

  147.   P+ e! S6 v& A/ g2 A
  148.         delay_us(30);   //延时30us
    , u3 r1 e$ }2 e+ f% a/ J( T

  149. 8 _% C! S6 l4 v* v
  150.         /*主机设为输入 判断从机响应信号*/ 8 G! v' R  s- E" g. A
  151.         DHT11_Mode_IPU();
    # t! n% E+ B! [' |2 n
  152. 2 y, a+ ]( Z  l+ V" E9 ]: T
  153.         /*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/   
    9 S/ R& z, K% z* v! o, |8 V
  154.         if(DHT11_Dout_IN()==Bit_RESET)     
    & |/ W. P% N0 b% ^2 n2 z& k
  155.         {+ M6 P3 U* s, t& M# k
  156.                 /*轮询直到从机发出 的80us 低电平 响应信号结束*/  4 H) p, s" ]  n) z0 \6 z
  157.                 while(DHT11_Dout_IN()==Bit_RESET);/ i- T% Z. z: V& Q8 r9 @& Q) }: }
  158. : U0 w  v# l: |0 l. P" Y
  159.                 /*轮询直到从机发出的 80us 高电平 标置信号结束*/; z! `0 h3 N& Q; G+ T; L
  160.                 while(DHT11_Dout_IN()==Bit_SET);4 q$ Y" y9 N6 ^; Y9 L* h
  161. " A8 O  `4 x) @- S2 C  M: C& ~0 r
  162.                 /*开始接收数据*/   
    & O( N+ r; n8 T" W$ I% d, t
  163.                 DHT11_Data->humi_int= DHT11_ReadByte();
    2 T/ H! E2 X! M1 A& {

  164. ) \: k. I- A: N, f
  165.                 DHT11_Data->humi_deci= DHT11_ReadByte();* |' \9 X3 B+ Y# q+ q# U0 L
  166. , N) B% M+ Y* M0 J9 y
  167.                 DHT11_Data->temp_int= DHT11_ReadByte();
    3 z% Y7 n  b; w" }8 P

  168. . I! }: f, y- \! q6 d+ ^
  169.                 DHT11_Data->temp_deci= DHT11_ReadByte();
    * T5 R) r/ R+ h, i/ L+ Z( p

  170. 8 C: D) D: v9 `5 C
  171.                 DHT11_Data->check_sum= DHT11_ReadByte();
    + ?! v4 r6 y8 L& G' s

  172. 8 R# w1 u: ^& A: V0 k

  173. % F' L/ B* l3 g6 w
  174.                 /*读取结束,引脚改为输出模式*/5 ~+ Z; e% t1 h* s2 e: b9 T: I
  175.                 DHT11_Mode_Out_PP();4 e) V  A# M7 s3 }* p$ ~
  176.                 /*主机拉高*/
    ' L9 \- Y7 J# C* O6 B" H& U/ x
  177.                 DHT11_Dout_1;
    5 N6 y, g! O' }

  178. 1 B4 C+ a2 {, h, b+ w2 f
  179.                 /*检查读取的数据是否正确*/7 i: `# S# M$ I) z
  180.                 if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)
    % d6 J6 t+ M1 G- k) K6 K
  181.                         return SUCCESS;
    2 K* d. u! Q, C* a3 I
  182.                 else ; E- s$ ?/ D& p. ?, x
  183.                         return ERROR;
    % Y+ g. J' G6 }; R7 C
  184.         }7 i* X* F, G2 @; r; y* V
  185.        
    1 b# i  O" {2 `/ S3 r) @
  186.         else
    4 R# [7 C$ B  h! G0 \7 h
  187.                 return ERROR;, j- Q( T7 O+ ^4 \
  188.         5 q) w6 }8 A/ Z$ t4 W
  189. }
    2 m4 x3 \' }" E; _  \  a& y

  190. , ]- j1 ?/ ]7 u4 ]3 ]; p

  191. . Y- E$ D/ \8 Z0 ?
复制代码
9 ]6 v7 ]% i. G5 m
3.main.c! \* M. N. ~2 @& t( V1 N
  1. #include "stm32f10x.h". s5 D  h5 ^5 N# \+ x5 Q
  2. #include "delay.h"
    - L: ^+ N0 W8 u( T* G4 m
  3. #include "usart.h"
    ; \& g4 n- r- b" L. v3 k8 L
  4. #include "dht11.h"
    & L: x/ o6 A, ^3 W- _  w, B
  5. # b1 ?  q6 x' |* }. T
  6. int main()
      x- g) D/ j3 x3 D! c
  7. {( `; H8 e0 N. G" q6 c, Q6 P3 Q
  8.         DHT11_Data_TypeDef Dht_Data;
    1 u" s' ~: p# j; ?
  9.         char Temp_Str[ 10 ] = { 0 };
    $ {; a% f/ K9 ~/ C7 U
  10.         char Hum_Str[ 10 ] = { 0 };
    ! r' G7 ^0 c7 C8 e% U. A  D; N
  11.         USART_Config();   //初始化串口
    ( l3 ~# X/ K3 u% m. f
  12.         SysTick_Init();   //初始化系统定时器
    ; O% h1 j) P$ R1 m* m
  13.         printf("\r\n***Dht11 温湿度传感器实验***\r\n");
    ' i# O. b5 X, x. x- u5 `0 t) s2 C
  14.         DHT11_Init();  //初始化DTT11的引脚
    " K9 D; i/ n' m4 c9 C7 O# ^; P
  15.         while(1)
    $ k/ B2 F* M1 t, ~  \0 c
  16.         {
    3 g" S" n: \$ V! A% y
  17.                         //调用DHT11_Read_TempAndHumidity读取温湿度,若成功则输出该信息
    & R7 @: A" c( R% o
  18. * h2 M' t8 N. N9 H& {
  19.                 if(DHT11_Read_TempAndHumidity(&Dht_Data) == SUCCESS)
    , w2 Y; K/ N% [+ s* K5 i
  20.                 {
    5 \) b0 Y4 s/ \3 \4 M! ^3 Y. D
  21.                         sprintf(Temp_Str,"%d.%d",Dht_Data.temp_int,Dht_Data.temp_deci);
    7 T0 B$ E' F& P( U6 \7 Z
  22.                         sprintf(Hum_Str,"%d,%d",Dht_Data.humi_int,Dht_Data.humi_deci);+ m3 P7 d2 }& _7 i( ]
  23.                         printf("温度数据为:%d.%d ℃\r\n",Dht_Data.temp_int,Dht_Data.temp_deci);
    ) t1 A; S8 V. h# o( \, h4 t
  24.                         printf("湿度数据为:%d.%d %RH\r\n",Dht_Data.humi_int,Dht_Data.humi_deci);
    + x# T) d" p" W/ j6 z( G
  25.                 }
    8 {& S7 ?. y* o5 d- w" N% \* `
  26.                 else
    & p/ b) C! B) [8 K
  27.                 printf("error\r\n");
    0 l) E* a" f# V) k6 i+ Z$ p- U

  28. : \  |; g! }) z. F0 f' j3 }* v
  29. 7 v9 M! {1 D4 d
  30.         delay_ms(2000);. C" X" X% `: a* \9 Q" w
  31.         }
    8 U  u2 b# h( z) j
  32. }
    " |- D  J# b# }. ?0 G( `
复制代码
; x. a. t/ M$ K; y3 o

% S: m$ H: M; ]$ u1 H! j. t4.串口显示
: ^: m: k$ \: \  o8 A3 g将开发板连接电脑,然后打开串口调试助手,就会看到温度以及湿度的数据
8 P. l: J9 {4 L# Z  q
8 d: B$ {( w4 w5 i
3cce415f69ab42c9a24402a6c427c894.png 2 T7 V# \* _) Y' D, T' ^4 p
. c$ Y" Q3 z* y1 \5 s
/ h# Q- _! A& M; W3 J0 S9 W
总结
' E; J" R0 M! U- j做到这一步算是已经完成温湿度采集并串口显示,有需要的话可以进行LCD显示。: u/ ~/ [! z# h" y; g
————————————————
+ v- i% M1 X3 U4 O4 Q8 a9 u6 O" |版权声明:清道 夫! ?$ ^% p# u% q6 p& P! [! v5 s
+ h4 \4 T1 ?+ [# O& @" s
. [7 |6 e! c( p
收藏 评论0 发布时间:2023-2-5 18:50

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版