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

STM32F103VET6实现采集温湿度数据

[复制链接]
STMCU小助手 发布时间:2023-2-5 18:50
前言6 I) o% \/ a1 b% o% u
了解DHT11温湿度传感器相关知识,进行DHT11传感器的开发及数据获取,并通过串口调试助手查看
) L7 G4 A7 D8 }: c! a+ v+ J
3 w# @7 X; x" r$ ?; ~5 C/ e3 Y一、温湿度传感器相关知识

2 Z: P+ ]& t! E& p0 b) _1. DHT11简介  L! M8 L4 ~3 E/ u# O; ?: j
DHT11温湿度传感器是一种比较便宜的常见的温湿度传感器,它的内部由两个元件构成,一个是电阻式的感湿元件用来检测环境湿度,另一个是NTC测温元件来测量温度,在测得数据后,两个元件会将数据传送给内部一个集成的8位的处理器来对数据进行处理,并将它们转换为数字量,这些数据可以通过串口传送给主机。DHT11温湿度传感器有四个管脚,只有一条是数据线接口,所以在传输数据时仅需要1个I/O就能同时传输测得的温度以及湿度,在进行程序编写时更加简洁方便。因为DHT11集成度较好,体积比较小,所以消耗也很小,抗干扰能力更强,稳定性较好,不易受到外界干扰。  K1 q! K4 h1 c7 K& f  f/ K9 e

- A  \/ w9 O' a, s7 e8 n1 WPin1 VDD 供电 3-5.5V DC
; F  V0 P2 y" i, XPin2 DATA 串行数据,单总线
! |- j4 i+ A' h% `+ z  E: q9 ~5 A1 p  IPin3 NC 空脚,悬空3 c( M8 n& p6 A6 a
Pin4 GND 接地,电源负极
/ v9 S3 `' m# J3 I: l' j' O* C2 ~
) u- C7 f6 z7 M+ @% q* ~
DHT11集成度很高,封装的很简洁,只有四个管脚,所以连接也是相对比较方便。DHT11管脚Pin1接一个3-5.5V的直流电源的正极,管脚Pin2为数据端,主要用于传输数据,但是在接线时需要加一个5KΩ的上拉电阻连接到主机MCU上,用来保证数据传输的稳定性,同时还要注意这个5KΩ是在管脚Pin2与主机之间的接线小于20m时才有用,在大于20m时就需要根据实际情况来确定需要加多大的上拉电阻来保持稳定性。管脚Pin3不起什么作用,只需要将其悬空不接线即可,管脚Pin4接地。/ S: e! o: c2 M" A: [7 q  a

! r& F- S" Q% c/ y' R

3 m$ F, a7 H7 Z9 B' {  t/ W2.数据格式
: Y2 @8 l7 l2 b$ I6 N* E  gDHT11和DS18B20不同,DHT11不需要配置,可以直接读取数据,一次完整的数据传输为40bit,先传输高字节的数据再传输低字节的数据,也就是低位后出,高位先出模式。
9 d) ]+ q% C8 T  f* {9 B1 ]数据格式: 8bit湿度整数数据 + 8bit湿度小数数据5 n$ X( [% n$ {9 \! g
+8bit温度整数数据 + 8bit温度小数数据# F: I) H, _/ ~" d4 [7 X! _$ P
+8bit校验和
" P$ Q# N# \; R6 A5 k) [1 p数据传送正确时校验和数据等于. N% {2 M' G$ v1 n) W4 Q; T2 t
8bit湿度整数数据 + 8bit湿度小数数据
6 [/ d& S3 ]) R0 b+8bit温度整数数据 + 8bit温度小数数据5 {& N* a. W- z5 c
所得结果的末8位。: O, R0 r0 c* ^7 a+ e. y  _8 H6 o

, s3 C5 R4 C! q

2 u7 K% o# G& B7 Q8 e9 P. l9 G3.数据传输
$ _  V( `1 R" C4 F& S数据线一开始处于高电平状态,用户MCU将总线电平拉低,表示用户要开始获取数据,然后将电平拉高并延时等待一段时间,等待DHT11回复,如果DHT11将总线拉低,表示已经收到主机信号,并响应主机信号,准备输出,然后将总线电平拉高,并延时一段时间,表示准备传输40bit的数据。然后将数据总线拉低一段时间开始传输数据,主要是进行2进制数据传输,传输0和1,并用不同的拉高电平延时时间来表示数据0和1。用户可以选择读取湿度还是温度,整数还是小数。并且数据传输是需要DHT11收到主机MCU发送的开始信号,才会开始采集数据传输数据,而且此时DHT11会转到低速模式。
# Q; s. B- v6 g+ L2 J
  ^; a. E# w: e8 `1 d
1d4a7e41310f44198a2a3914b9f59db3.png   E# a) x+ K+ c. n& E" u
- P9 O  s" G. J# K; H/ x' _
总线在空闲时因为上拉电阻会处于高电平状态,主机用户MCU会发送信号将电平拉低至少18us,太短DHT11可能会检测不到主机的起始信号。之后主机会再将电平拉高20-40us,DHT11识别到后,会将电平拉低80us,表示DHT11已经接收到主机发送的开始信号,之后再将总线切换到输入模式,然后DHT11会再将电平拉高80us表示竹北开始传输数据。之后会再将电平拉低,然后开始传输数据。
* a% y9 S: B$ u) ~8 V" H
! U' S! I& k, K2 B5 p4 P( O9 P- p当接收到主机的开始信号后,DHT11会将总线拉低80us来发送响应信号,表示已经接收到,然后会将总线拉高80us,并准备发送数据,每一位的数据都以50us的低电平间隙开始,就是每两个数据之间都有一个50us的低电平信号来表示一位数据传输完成。DHT11用电平拉高延时的时间来表示数据为位0还是1。通常用拉高26-28us来表示数据‘0’,用拉高70us来表示数据‘1’。当最后一位数据传输完成后,DHT11会将总线拉低50us,随后总线又会因为上拉电阻将总线拉高,并处于空闲状态。5 q: s  |7 q. T

1 n. \  O! |" n/ eDHT11读取数据“0”时序图
( T. B* p8 P- A3 U2 u: [& U; {; V* g* u) Y% p8 g+ T
ea92ef3f20334c68aa75e8b83aefa06f.png 0 }% \- j8 c$ ^4 K6 q
2 ~5 u& l2 O9 R5 Z% t  i
DHT11读数据“1”时序图
* U  h$ k( @0 }* h" V; x/ f) h& J* P3 ]  E5 m' [
d7d734cf63a942ecbe48dc4f2ae1fc4b.png 1 ^- p/ [, H# ^  w  n6 i5 B

, ]; b! Z8 N5 F6 J) d5 Q8 b" s
3 l) K4 [5 k. x
二、程序实现' s( v1 _4 _* C/ y
1.dht11.h
' ~' Z* g% O' @/ S( jDHT11的程序实现主要是根据它的读写时序来实现的,因此在进行程序的编写时要根据它的读写时序进行模拟,实现单片机与DHT11之间的数据通信。# x, R! {, z# Q, g; |7 A- ^6 j

$ z( e6 i8 ~5 ?代码如下(示例):. q6 W* B+ [! i3 r
  1. #ifndef __DHT11_H6 ]5 r; |- ~' V& y
  2. #define __DHT11_H
    " M! G9 q& j% G; B& M5 ]! ~
  3. - }4 F# ], `, T7 Q% m$ l
  4. #include "stm32f10x.h". Q3 R5 M. e' _- ]* z8 g$ z; e& \4 T- g

  5. 0 y2 V6 U* ?$ r
  6. typedef struct
    + {' c% ~3 l3 @# Q- T' j: P
  7. {
    ( j5 q- V% o  r/ o1 C' g
  8.         uint8_t  humi_int;                //湿度的整数部分
    2 Q5 j( r5 q% c8 S
  9.         uint8_t  humi_deci;                 //湿度的小数部分$ ?( X9 I: B; i6 @
  10.         uint8_t  temp_int;                 //温度的整数部分
    9 c2 @: r2 ^5 a7 x: b1 d+ w4 d% X
  11.         uint8_t  temp_deci;                 //温度的小数部分
    ) V  D( O5 n* m. @9 H- @
  12.         uint8_t  check_sum;                 //校验和
    1 C- U* z# Q; j1 m7 n
  13.                                  2 W! Z7 i, x! x* \( v4 M6 {
  14. } DHT11_Data_TypeDef;8 V8 K0 t" x- J

  15. * u  x; @4 |7 g, T4 A' k  |
  16. , X  a5 E" H5 M$ v( C3 j* e' F4 b
  17. 8 ~7 w+ b, B3 X# L1 K2 {" N
  18. /************************** DHT11 连接引脚定义********************************/
    / v9 S* P& D' X) H/ [. o; c4 O8 ^9 U
  19. #define      DHT11_Dout_SCK_APBxClock_FUN              RCC_APB2PeriphClockCmd+ P  x3 w3 f1 X+ C% o
  20. #define      DHT11_Dout_GPIO_CLK                       RCC_APB2Periph_GPIOE
    9 s( i6 T) b- }, Y! a
  21. ; u) ~3 b2 ]1 R4 m
  22. #define      DHT11_Dout_GPIO_PORT                      GPIOE! E0 Q% j$ H! b3 j* [, z
  23. #define      DHT11_Dout_GPIO_PIN                       GPIO_Pin_6/ e1 t0 V  O& l4 u: y
  24. 8 |) U4 k6 P6 \. R8 A  C% j) |7 M
  25. ! i9 p& J% E4 \9 h/ y5 S

  26. 0 P) E4 p  H% f, }
  27. /************************** DHT11 函数宏定义********************************/  `: z( P# i  N! C; Q8 B* ?
  28. #define      DHT11_Dout_0                                    GPIO_ResetBits ( DHT11_Dout_GPIO_PORT, DHT11_Dout_GPIO_PIN ) 6 y9 N. A% c) {* `( p/ Q
  29. #define      DHT11_Dout_1                                    GPIO_SetBits ( DHT11_Dout_GPIO_PORT, DHT11_Dout_GPIO_PIN ) 6 E6 M/ P& h3 l8 B2 d
  30. # W  g- p( v! G3 Q, \) c# p
  31. #define      DHT11_Dout_IN()                                  GPIO_ReadInputDataBit ( DHT11_Dout_GPIO_PORT, DHT11_Dout_GPIO_PIN ) * ^- b/ z3 ^+ Q0 i

  32. 1 t( W' K$ Q7 c! |

  33. 0 t( R3 v4 s5 X! I0 j% a
  34. 5 k  P. \0 x/ n
  35. /************************** DHT11 函数声明 ********************************/
    # F8 }, D9 {& V  p0 O5 d- F
  36. void                     DHT11_Init                      ( void );: P$ u. |  m5 |4 G! `* l
  37. uint8_t                  DHT11_Read_TempAndHumidity      ( DHT11_Data_TypeDef * DHT11_Data );
    % V: a, c; `( x

  38. ! V0 i4 B+ I8 w7 c/ ]
  39. #endif
    ! y# i5 z" S) ~+ m* h) N; j
复制代码
" T( X+ {, `+ T# d4 t9 n
DHT11用到的数据总线是PE6,接线时,DHT11数据线接到PE6,以及我们需要用到的函数的声明:7 c' H* r0 q$ l
Void DHT11_Init(void)为DHT11的初始化函数;0 B" U6 I, R' |# B+ V
uint8_t DHT11_Read_TempAndHumidity ( DHT11_Data_TypeDef * DHT11_Data )为DHT11的数据读取函数,这个函数会将读取到的数据赋值给DHT11_Data结构体里的变量,然后还会有一个返回值判断是否读取成功;
( v9 o) P. c: R* {# `* Q2 o

. L/ \$ d( J/ c/ }2.dht11.c1 G( r% x: s" A# e4 b2 y
代码如下(示例):; q3 P2 }* ^( C! W! j- Y
  1. #include "dht11.h"
    0 z+ [: j* T# N* h/ _
  2. #include "delay.h"5 `) p& a% ~9 g+ q
  3. ) \/ c4 G7 H) N8 a  g9 V- N
  4. static void                           DHT11_GPIO_Config                       ( void );
    - N2 d! n+ U  u  i
  5. static void                           DHT11_Mode_IPU                          ( void );
    . G# z" T" y* t8 P
  6. static void                           DHT11_Mode_Out_PP                       ( void );
    $ c& ~/ K7 x8 Y& T2 X  P' B: h% P
  7. static uint8_t                        DHT11_ReadByte                          ( void );
    # N- U6 T8 i  _5 j

  8. . @+ `$ ~7 u9 C* b
  9. & x% u% q: Q) A  ~( `* y
  10. /*** M$ b4 q/ @2 s* m3 J
  11.   * @brief  DHT11 初始化函数5 @: I4 ^( u1 A0 X- w  O2 J
  12.   * @param  无
    + H3 x3 h5 f, y
  13.   * @retval 无1 P6 r, t/ V0 ]
  14.   */) {- w7 |' m8 t
  15. void DHT11_Init ( void )
    - y) G4 m6 O6 z. m/ [% v. O
  16. {
    " T7 c; n* v' N; ^6 F7 z7 N
  17.         DHT11_GPIO_Config ();3 B8 m# v  n. N9 J- e. B
  18.         + J- z5 V4 Q/ \5 c& r6 A
  19.         DHT11_Dout_1;               // 拉高GPIOB10
    ' v4 Y$ C' [6 t, D& C
  20. }. e. I# z5 C. d3 o2 M' q7 c

  21. ' R& l) g+ M' ~% N
  22. /*1 B$ P  Z0 U" m4 @$ Q7 A
  23. * 函数名:DHT11_GPIO_Config4 b$ J5 N  ?8 i9 S4 u% r; Q
  24. * 描述  :配置DHT11用到的I/O口
    2 O2 g1 A* E! j0 x
  25. * 输入  :无& p! }5 D4 ?+ f) u0 i
  26. * 输出  :无, M3 m; f+ ~$ ~5 T9 q) B" t* x* w+ G+ c
  27. */
    ! m) T2 C" G& Z7 r
  28. static void DHT11_GPIO_Config ( void )
    ! t) x7 ~& H: {! l2 t, ~& l
  29. {               
    ; O0 s6 I  y$ ]$ k6 @! b$ ]; O9 ^
  30.         /*定义一个GPIO_InitTypeDef类型的结构体*/
    / v$ q( P; m) C2 L& r$ v) t5 A
  31.         GPIO_InitTypeDef GPIO_InitStructure; + F% ]) [8 s2 C# f) ~% W
  32. + N3 j, C1 w  N$ G, B' A! ?
  33.        
    - z+ @9 q! j9 {. C4 B
  34.         /*开启DHT11_Dout_GPIO_PORT的外设时钟*/
    4 f, a/ b! w2 U( v, g! Z
  35.   DHT11_Dout_SCK_APBxClock_FUN ( DHT11_Dout_GPIO_CLK, ENABLE );       
    ' _8 w& t0 W4 P2 g+ b( r2 w
  36. . |: _* m5 ?* U7 w4 N. ?9 ~* A' y
  37.         /*选择要控制的DHT11_Dout_GPIO_PORT引脚*/                                                                                                                           8 e: ?( n$ B7 t) X3 O4 u
  38.           GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;       
    , U3 R5 {! P" T& R, t
  39. 0 W& W$ j6 j+ f; D
  40.         /*设置引脚模式为通用推挽输出*/
    , F7 [1 l$ i& Y2 F% I
  41.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   4 q- I1 h' B( g2 q- B
  42. % k. a- m: E8 W; L! I# p
  43.         /*设置引脚速率为50MHz */   3 C- D5 O% W& {  C3 |
  44.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    ( K" z- X3 A+ |4 [# X0 d

  45. , D3 W  ]' ?3 b' O* f$ q
  46.         /*调用库函数,初始化DHT11_Dout_GPIO_PORT*/" v9 w- c4 ?( ?3 a; [
  47.           GPIO_Init ( DHT11_Dout_GPIO_PORT, &GPIO_InitStructure );                  
    0 T" ?8 n/ ^. k" L- k3 Q
  48.        
    ; y( A7 D& Z; g3 D2 X) g
  49. }
    2 F& {0 V" U! |
  50. 9 K3 Q# Z; g8 O2 V& I
  51. /*
    ; I( K5 v9 L% g+ M, s
  52. * 函数名:DHT11_Mode_IPU
    2 S/ y! {' ?, N1 @$ ^
  53. * 描述  :使DHT11-DATA引脚变为上拉输入模式4 i8 c& x! w; ?
  54. * 输入  :无6 _" t1 j: A) o8 H
  55. * 输出  :无
    " w3 a& S& t) |0 B- Y
  56. */
    # Z) W% ~' j# V; k' W
  57. static void DHT11_Mode_IPU(void)
    # C, y$ x- l# d/ ?! L3 n: C, X
  58. {! a' Y* u* `$ l! r
  59.           GPIO_InitTypeDef GPIO_InitStructure;9 F- B. u3 l% ?4 j6 |. w# _

  60. ) j: E: B; ~5 [7 ^! }0 y
  61.                   /*选择要控制的DHT11_Dout_GPIO_PORT引脚*/       
    1 @7 C8 Q* q' N# J
  62.           GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;
    1 W/ j- j5 E, T# ^/ m
  63. ' L- Z# T3 r/ B, k/ b0 L4 H) z( ^
  64.            /*设置引脚模式为浮空输入模式*/
    : U9 [0 Z! a- f
  65.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; 7 I, H8 {9 B9 ^" _

  66. 6 x: W0 N5 A& v. p3 o) E
  67.           /*调用库函数,初始化DHT11_Dout_GPIO_PORT*/
    $ H1 `# E2 X2 Y, ^% r2 ^
  68.           GPIO_Init(DHT11_Dout_GPIO_PORT, &GPIO_InitStructure);         
    ( ~$ t3 s; J: U& u$ B
  69.        
    ! x) H9 \$ R+ G* C: Z
  70. }3 u- W$ ~: @" u. J3 \( _
  71. * }; \: l# ~. E2 J/ L7 i' \
  72. /*
    ! H' `  G# K4 s6 S8 \% K) H
  73. * 函数名:DHT11_Mode_Out_PP( J% @  l% a& W
  74. * 描述  :使DHT11-DATA引脚变为推挽输出模式& V0 X% q) g' T9 ?8 ^7 F+ [) f
  75. * 输入  :无
    ! F- C) I/ n: z) v
  76. * 输出  :无+ b, u6 `6 t  V
  77. *// M) |8 x1 z. X, G; R! x
  78. static void DHT11_Mode_Out_PP(void); C& t& J5 }0 o& E5 @2 E
  79. {3 v+ O9 j- e  v7 r
  80.         GPIO_InitTypeDef GPIO_InitStructure;+ o: A; n1 S/ q

  81. . ?( ^2 Q+ @# q
  82.                  /*选择要控制的DHT11_Dout_GPIO_PORT引脚*/                                                                                                                           : u9 A3 G/ D. H  @1 q' w
  83.           GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;       
    2 n3 N8 h* l$ E; E8 Q

  84. + o$ m' T: p  {) s
  85.         /*设置引脚模式为通用推挽输出*/
    - z5 a+ R3 ]" P
  86.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
    ) v' i( S# \9 R# }" V

  87. ; x: ]3 t: n, h8 v. x" e( H
  88.         /*设置引脚速率为50MHz */   & D, Q% _1 J% A$ a/ A
  89.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;7 E+ u) w+ j, k2 d" B6 \& [4 }2 J$ V

  90. * K$ @  \! I% Q1 F6 T; Y9 U# h
  91.         /*调用库函数,初始化DHT11_Dout_GPIO_PORT*/2 G: R- n, {! |$ Y, G$ m+ V4 L
  92.           GPIO_Init(DHT11_Dout_GPIO_PORT, &GPIO_InitStructure);                  
    ' e! P' e% S0 t6 X3 q; ?
  93.        
    # @5 E3 X9 b: s) e
  94. }
    6 h7 X+ q: W. y- b

  95. - L& t* \* w* ~2 Y; m0 Q" s% j
  96. /*
    ; V; E8 L6 b5 n" s' W" J3 `1 g
  97. * 从DHT11读取一个字节,MSB先行
    : i* H( l! N* g( l2 ]2 J0 F1 L# k
  98. */
    / y7 Q6 ^7 \2 Z; F% \" P, {
  99. static uint8_t DHT11_ReadByte ( void )  r+ n8 v2 l% B0 O3 x; O
  100. {7 t) b" _7 ^" R
  101.         uint8_t i, temp=0;
    2 J$ S5 |  M  Z' w
  102.        
    8 o$ Q. y+ b0 |9 c

  103. $ v3 x% H0 L! Z9 A/ \( g9 Y
  104.         for(i=0;i<8;i++)    1 n# C9 k# [0 A) e
  105.         {         
    2 \) L- s- w- R2 s0 h$ S
  106.                 /*每bit以50us低电平标置开始,轮询直到从机发出 的50us 低电平 结束*/  6 i- n* t( `! ^
  107.                 while(DHT11_Dout_IN()==Bit_RESET);* P" w" f; X) U7 p8 K
  108. $ [4 j2 ?+ H3 j$ v) x. k) u) Y+ ^
  109.                 /*DHT11 以26~28us的高电平表示“0”,以70us高电平表示“1”,% W2 z6 X& s$ `! w
  110.                  *通过检测 x us后的电平即可区别这两个状 ,x 即下面的延时
    " L# W8 H! t8 Q- B" B
  111.                  */5 y0 d! N5 C& F, i% l5 ~. ~
  112.                 delay_us(40); //延时x us 这个延时需要大于数据0持续的时间即可                     
    ! _8 F" U% i7 n( a+ m

  113. : M6 a% j/ t1 C8 s" t7 `  Z
  114.                 if(DHT11_Dout_IN()==Bit_SET)/* x us后仍为高电平表示数据“1” */  x7 M/ N& j1 }) M" J! D9 _# J
  115.                 {
    0 T+ C" m; K3 I9 s3 w
  116.                         /* 等待数据1的高电平结束 */
    " r& `2 Z+ K- Y( F4 z
  117.                         while(DHT11_Dout_IN()==Bit_SET);
    9 I' q* ~1 n  S  O' p

  118. 6 o$ b) {$ o. `% I
  119.                         temp|=(uint8_t)(0x01<<(7-i));  //把第7-i位置1,MSB先行
      p4 g4 s- ~2 Z% x6 O* S
  120.                 }( S' |9 }' n" a' ?% g) \( }
  121.                 else         // x us后为低电平表示数据“0”
    7 W% Z$ B( c0 _5 @/ x
  122.                 {                           2 @) s( v7 v% z2 X3 m- n" _- G" f4 e
  123.                         temp&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0,MSB先行
    + @7 H! M& {. g7 {4 S5 U6 @
  124.                 }
    4 l" p  K/ a# L/ V
  125.         }
    / A6 `3 W$ B% d5 b( s) U
  126.        
    " @1 g! O( ^! l" E; l% u
  127.         return temp;2 G0 b# s/ x' W9 n
  128.         + v8 M, P/ O& Z/ _/ y  j+ l0 B
  129. }
    $ A% \1 \2 L4 H0 O2 P  Z

  130. $ D6 R$ o- i6 ~. R# y* k0 y. i6 l
  131. & C; u6 n+ P6 A. }" T3 I. f
  132. /*
    " Y2 \( b% t$ q: V
  133. * 一次完整的数据传输为40bit,高位先出
    9 T6 L# V* w$ x2 I3 r- R* F
  134. * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和
    # B4 L5 ~/ t# T2 l# \  C
  135. */
    2 ?9 j, P9 f; i2 [1 ]
  136. uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)/ E5 z9 H" ~# Q0 F' y
  137. {  
    3 j) ?  X- a$ D# b
  138.         /*输出模式*/" f- E5 e( T3 M; x( n. Z
  139.         DHT11_Mode_Out_PP();: r8 W& N2 q3 x* e: K. ^' |  B
  140.         /*主机拉低*/
    9 F( R& Y! K! w0 Y( L
  141.         DHT11_Dout_0;
    ; L9 |" C0 o3 s, \+ W
  142.         /*延时18ms*/
    $ M0 `- a% O- W( V5 m
  143.         delay_ms(18);" B0 X1 Z# R% H5 J( Q/ e
  144. % q. [9 k7 S& `& E* `1 q" ^( f+ @0 L
  145.         /*总线拉高 主机延时30us*/  J1 _6 J( t, c, y' K9 G5 l2 S
  146.         DHT11_Dout_1; # P$ {% l: k0 X# a+ {) D. @1 [
  147. ' R( `: P" M  @! q
  148.         delay_us(30);   //延时30us
    % |2 a' Z6 m0 _: M6 _! Q

  149. ) ?2 \' C7 G# b8 v' d( M' p
  150.         /*主机设为输入 判断从机响应信号*/
    ) D5 h, c8 a% z  j- h
  151.         DHT11_Mode_IPU();
    0 I- @/ c8 o, d
  152. & v0 g7 q2 ?" p, s: u4 x4 B; q6 J
  153.         /*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/   " n6 c( V- ~/ b- V
  154.         if(DHT11_Dout_IN()==Bit_RESET)     & W% L# @8 @+ ~! U
  155.         {
    ) F, y( ?# q5 p. y
  156.                 /*轮询直到从机发出 的80us 低电平 响应信号结束*/  
    4 u6 p7 r& u1 N! ?& X8 a) t
  157.                 while(DHT11_Dout_IN()==Bit_RESET);
    ! y) q% \3 i# n  M' C: k

  158. 5 N' N" ?5 @3 L" v
  159.                 /*轮询直到从机发出的 80us 高电平 标置信号结束*/4 y- c* g( R8 ]+ @! U1 x, ?
  160.                 while(DHT11_Dout_IN()==Bit_SET);
    / j5 R5 [1 g4 R/ s% g. U3 y3 T) b# m

  161.   j$ Z; ^' _" ]( p, E+ V
  162.                 /*开始接收数据*/   / S; X9 Q: a2 P4 p4 F
  163.                 DHT11_Data->humi_int= DHT11_ReadByte();
    - i& C/ O; Q* x* R# N
  164. 5 A0 M! |4 _, X$ r
  165.                 DHT11_Data->humi_deci= DHT11_ReadByte();0 o. D* C, X% Q: n

  166. / Q3 H( n/ R& A! n
  167.                 DHT11_Data->temp_int= DHT11_ReadByte();
      Y8 b2 o2 \/ c; D  r8 t

  168.   }- h/ ~8 d. P' U' }; r) d& P
  169.                 DHT11_Data->temp_deci= DHT11_ReadByte();
    : B8 R' ]; n# A7 f6 n9 x; P& O

  170. $ {5 J7 }: |. H4 X1 I
  171.                 DHT11_Data->check_sum= DHT11_ReadByte();1 K: Q3 y5 r' |: h
  172. 6 h/ ^! X( n, q; @! x
  173. & y; `$ K: p- j9 T% n# V0 P
  174.                 /*读取结束,引脚改为输出模式*/
    5 j  r3 J  T" C: B
  175.                 DHT11_Mode_Out_PP();) r& ^. Q- }& x5 x
  176.                 /*主机拉高*/( b6 s$ T2 C2 S, {% a2 R
  177.                 DHT11_Dout_1;5 @; U6 b8 k! `% T

  178. 0 U7 U- ]1 r& _/ i
  179.                 /*检查读取的数据是否正确*/
    3 T+ B- M6 e: S9 S) ~* ~
  180.                 if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)
    0 j3 b' C( z3 v: F. F# \! @, k- n
  181.                         return SUCCESS;( I3 j4 E4 x( I: P  c; F7 P
  182.                 else
    * h' N8 L' m. h8 W
  183.                         return ERROR;2 l2 C8 q& z# ^- J& g/ v8 w
  184.         }/ G& t9 k' ?( M: o2 ^* M
  185.         9 ?% D! f0 P" y+ q
  186.         else
    + m8 S) g/ G1 R% k, I2 C" k% `& U
  187.                 return ERROR;
    . m$ C: b% ?" c0 W7 f) t0 X
  188.         ' f% ]. V3 W  q  w& [
  189. }
    * C& L# K7 @8 C: l: v
  190. ; Z) M0 q+ U/ l
  191. ' e9 h9 F4 W$ Z( l5 q, Q# P) q
复制代码

$ l" U8 a) e7 s3.main.c
# s9 Y) l  |& @& O5 o- @
  1. #include "stm32f10x.h"' z0 l' n4 h2 F9 ]( }' y. e" t+ u0 E! @
  2. #include "delay.h"
    ; s. \; z1 Y1 a
  3. #include "usart.h"+ e* _) L% r2 z3 _3 @+ F
  4. #include "dht11.h"
    " u. U0 ?6 f( [( o3 R6 u
  5. + U0 P4 A6 o1 ]1 Q- P
  6. int main()
    ; C+ h' D4 X8 ^: W6 `
  7. {
    & O) v' l* P8 G0 Q# d/ G
  8.         DHT11_Data_TypeDef Dht_Data;  v/ Y* N, k! U0 f0 B, v/ o- l
  9.         char Temp_Str[ 10 ] = { 0 };' o' t' D" z& C5 k/ G- u
  10.         char Hum_Str[ 10 ] = { 0 };& R' L; Y" I7 D7 W, H' \3 X# x
  11.         USART_Config();   //初始化串口
    . r! p, |+ h* f" Z/ w, w
  12.         SysTick_Init();   //初始化系统定时器
    % d  T# E( }' X5 Z
  13.         printf("\r\n***Dht11 温湿度传感器实验***\r\n");! g" ]0 Y- g! R& ~" k) i$ _& ]' W
  14.         DHT11_Init();  //初始化DTT11的引脚
    5 r8 A7 I' H' c: o1 m0 |
  15.         while(1)* A2 e# W- W, |
  16.         {3 ?& ]; a4 n* C! I9 e9 N% X
  17.                         //调用DHT11_Read_TempAndHumidity读取温湿度,若成功则输出该信息
    * H, m$ |. e2 b$ x2 P4 x

  18. : o! x' r* ~7 d) w
  19.                 if(DHT11_Read_TempAndHumidity(&Dht_Data) == SUCCESS)7 u4 }% u: B1 U; t
  20.                 {; Z; s: [: {  N6 H: ?0 @& D* F' f3 g
  21.                         sprintf(Temp_Str,"%d.%d",Dht_Data.temp_int,Dht_Data.temp_deci);
    4 @: [- o- s, d- ]- o% M1 K% |
  22.                         sprintf(Hum_Str,"%d,%d",Dht_Data.humi_int,Dht_Data.humi_deci);3 u: j1 F( O1 Q6 V* l8 O
  23.                         printf("温度数据为:%d.%d ℃\r\n",Dht_Data.temp_int,Dht_Data.temp_deci);
    : O7 c1 L5 j' F6 O5 _
  24.                         printf("湿度数据为:%d.%d %RH\r\n",Dht_Data.humi_int,Dht_Data.humi_deci);3 _; N/ V* y3 f& ^
  25.                 }
    3 a6 w3 y& P/ s" i
  26.                 else
    3 w& J# e  z, W# P
  27.                 printf("error\r\n");& H$ b6 l! }* ]3 {

  28. 5 Y5 H$ h& @$ f8 F

  29. - E* a1 ~, U; y7 ?
  30.         delay_ms(2000);
    " s" Q2 r3 p( b9 w6 I- {
  31.         }
    9 _/ e! p$ E) a4 @  m: }( K# }
  32. }+ J: H$ ~3 N  e; z7 W  R" _. v
复制代码

/ s. R! f1 V; g/ |; j% L3 ]4 m4 T1 |4 J
4.串口显示* i0 K" N0 T) @1 m$ ]. R) {
将开发板连接电脑,然后打开串口调试助手,就会看到温度以及湿度的数据
! {. r1 ?1 X. D3 Z9 w, M8 F" x3 w9 t0 c6 ]$ a, b1 R% c# }
3cce415f69ab42c9a24402a6c427c894.png 8 F5 K2 ?, p' K

5 N- H) n5 X* ]2 E' d' P: q3 y) ]

" ?! f5 T2 [6 I3 ?0 \/ B总结
" q2 E7 x6 P$ B做到这一步算是已经完成温湿度采集并串口显示,有需要的话可以进行LCD显示。7 E9 S* O+ J1 e+ S1 w7 H
————————————————& b/ N, W, d/ D& }6 Z( ~
版权声明:清道 夫
4 Y$ U6 [" B# B! O. |3 |; t
* u1 K* ^  C1 @4 |! x# z8 Y* c* j5 `9 o* d$ F! J
赞 收藏 评论0 发布时间:2023-2-5 18:50

举报

0个回答

所属标签

相似技术帖

官网相关资源

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