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

【经验分享】STM32 HAL库驱动DHT11读取温湿度程序

[复制链接]
STMCU小助手 发布时间:2022-4-12 10:00
sys.h
5 e. j" g5 F: B5 J" T6 f
  1. #ifndef _SYS_H_; {+ B5 Z1 h8 A" c# A  w
  2. #define _SYS_H_
    1 p9 U7 [* h3 O# r0 l
  3. 9 p. v- ?  o& R0 H8 b1 h$ }
  4. #include "main.h"
    6 d$ w* P3 N4 U- e. [1 z! m
  5. 9 R) i9 Q; N$ U; d) A7 v
  6. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))2 v3 K% ?! o) g1 [
  7. #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))& ~4 D& O: I) K1 V% Q8 a
  8. #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
    ( h' N: A. g+ l0 R; l

  9. ; n' L2 Y; c9 ]; C1 p* ^( U
  10. #define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C # F  p7 ?( ?9 S8 g4 }
  11. #define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C
    / m) e: m6 C6 d: R7 j* y
  12. #define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 3 {. C$ ^: b- w  F% j5 b+ f
  13. #define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C
    # r+ T% L# r* B
  14. #define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C
    5 I: F* d$ ?4 F- `
  15. #define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C   
    * _$ K  }" J; D! G
  16. #define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C   
    2 ^7 M0 f4 l( u2 L& S" ~2 ~8 U9 y

  17. ; p  \  Q, T( W' ~: s. a! y" R& ~
  18. #define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808
    $ V- C+ C3 ~1 Z/ X8 u" ~5 r; v
  19. #define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 " r5 O+ G2 w. o/ y% n1 n
  20. #define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 ' L$ |5 y2 |+ T9 o% H( d
  21. #define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408
    & J. c5 g7 I- s: h
  22. #define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808
    $ J' I, i) U, h8 Z+ s$ x
  23. #define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 : H! I  w/ D0 K; o% U2 m; U
  24. #define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 1 L. ^: S0 Y. ~( `
  25. 2 S4 z, K! l0 x3 w
  26. #define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //' x" r0 O, o/ E3 S3 d, o
  27. #define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //1 K2 _- T: v* A' p8 H: q; z3 X
  28. . o7 G: _! Y- s3 S, i  r+ r1 e
  29. #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //! n' q" |. b4 ]. X. H
  30. #define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //* P/ H  T+ G; z' L' \& s

  31. 0 B3 P; p4 [7 ^* u; x
  32. #define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //
    4 S; X+ k2 |% E/ `/ u- ^& m  A* n
  33. #define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //2 u* H  I/ U/ g5 Y/ }

  34. # \' I: W( l/ K$ q# q& ~
  35. #define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //
    1 Z; ?: y- T9 t' d1 _& z
  36. #define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //
    . {8 [; T4 M' H  Q" D* W3 \( s" N3 d
  37. ' t; N) x3 C# L
  38. #define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //
    " R6 D  p2 [0 z) J2 K$ d. }6 j
  39. #define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //
    . X7 L# T3 W/ J6 _) c8 \) f2 Z
  40. 7 n: E1 B/ k5 w* x$ r
  41. #define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //1 S" p0 \5 u, j: e
  42. #define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //
    0 p8 q/ R- P4 N3 a+ E6 T' }9 z. f

  43.   I+ r7 x( P1 s1 o' |$ E; E' r+ N3 S
  44. #define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //
    1 ?% B9 L5 L! ~5 r
  45. #define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //0 W6 R% Q0 [2 y! u; ?$ Z% U
  46. #endif
复制代码

; z9 I/ T+ X2 h$ ?3 Kdht11.h
: ~2 i6 X; O# v6 _+ R
  1. #ifndef __DHT11_H
    : P" E$ O) e7 d. l
  2. #define __DHT11_H" ]  m& i1 P; n  ^6 [
  3. + l- S" _+ C# Z* n
  4. #include "main.h"2 W- [) f8 U+ H* G! G$ Z
  5. #include "sys.h"
    ) e+ G4 ?" a+ f) M
  6. ; ?, C; a% _+ I
  7. typedef uint8_t u8;
    7 `" [( n1 C- v' B4 n5 ^. |  J( }$ h+ h
  8. typedef uint16_t u16;
    0 i& h' j4 w* F
  9. typedef uint32_t u32;( D3 Y  x5 j9 V
  10. & X2 v, s6 e9 `8 h$ R) {
  11. //IO方向设置
    : a$ c& `+ E/ \. b) B$ H8 P& z
  12. #define DHT11_IO_IN()  {IODHT22_GPIO_Port->CRH &= 0xFFFFF0FF;        IODHT22_GPIO_Port->CRH |= 8 << 8;}        // PC10 IN  MODE
    7 r2 H0 Q( f( i0 {
  13. #define DHT11_IO_OUT() {IODHT22_GPIO_Port->CRH &= 0xFFFFF0FF;        IODHT22_GPIO_Port->CRH |= 3 << 8;}        // PC10 OUT MODE+ |: n- i+ |; Y8 S
  14. ' b+ V8 q1 I" K5 C. l
  15. IO操作函数2 P! ~: Q/ r% |( B( @0 X) u! j$ Y
  16. #define        DHT11_DQ_OUT PCout(10) //数据端口        PC10
    1 N: {, @" \8 F; B8 \9 n
  17. #define        DHT11_DQ_IN  PCin(10)  //数据端口        PC10/ z  w2 X2 s4 `% f( C

  18. # S/ e5 O  h7 C- o/ y
  19. u8 DHT11_Init(void);//初始化DHT111 c9 ^/ i: B6 v$ V* \, o2 S
  20. u8 DHT11_Read_Data(u8 *temp, u8 *humi); //读取温湿度4 y/ c& h1 s0 S  T+ o5 [
  21. u8 DHT11_Read_Byte(void);//读出一个字节
    5 B9 \9 @. g! g& n* r1 y+ k8 G) U
  22. u8 DHT11_Read_Bit(void);//读出一个位
    : J/ G' W4 T, S$ k5 f
  23. u8 DHT11_Check(void);//检测是否存在DHT11. K* v( R6 K1 x! k0 H  ^3 [
  24. void DHT11_Rst(void);//复位DHT11& b3 k" T2 T" j# O( Q" }$ q
  25. u8 DHT11_Read_Data_Float(float *temp,float *humi);
    , ?/ K( [1 K: X
  26. 9 g: @2 \( F6 Q1 d% }
  27. #endif
复制代码

" k3 }8 c' X* ~dht11.c
( d0 ~4 I( u, J
  1. #include "dht11.h"9 a8 D4 V6 `- w% y8 [  _
  2. , J, B9 ]6 c; G8 t% \* Q4 }
  3. //复位DHT11
      s5 w3 b* `2 `& _
  4. void DHT11_Rst(void)8 e! s- B) {6 P
  5. {/ O. R1 V* d/ U
  6.     DHT11_IO_OUT();         //SET OUTPUT
    " \2 x8 w4 C: B1 e
  7.     DHT11_DQ_OUT=0;         //拉低DQ
    & V8 Q. z( S' M
  8.     delay_ms(20);            //拉低至少18ms,(DHT22 500us)
    3 S7 j! h/ U+ d( d8 Q' [
  9.     DHT11_DQ_OUT=1;         //DQ=1
    ! Q" T5 S) V- j  b6 J
  10.     delay_us(30);             //主机拉高20~40us
    2 x% w* t) R# ]" `! i
  11. }
    2 L3 G0 n; f. S

  12. 2 ?2 g; ]- A, O7 ~% }  T
  13. //等待DHT11的回应
    0 h) i$ p, `: C3 Q
  14. //返回1:未检测到DHT11的存在
    ) i$ X1 p% r  B
  15. //返回0:存在3 Y% w6 L7 {, h+ W
  16. u8 DHT11_Check(void)
    & L% |% {& j3 Q$ `6 R+ ~
  17. {
    ) m, e, y. m0 i
  18.     u8 retry=0;
    % Q* V$ y4 C$ Z
  19.     DHT11_IO_IN();//SET INPUT" T1 T& g: A. G2 V
  20.     while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us7 C6 h5 \6 |. A8 d
  21.     {
    % E; ^+ j) u  q% p4 n- S
  22.         retry++;
    # |" q' [' u! m2 m
  23.         delay_us(1);1 b1 L5 L* J2 F, X# U. v
  24.     };
    7 {7 }8 V# k9 \4 \2 R4 ?0 x
  25.     if(retry>=100)return 1;
    # ^  F9 g* O8 L- b+ S9 ?. a
  26.     else retry=0;0 E" C  z( q6 S4 j7 y1 ]
  27.     while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us0 Y( H  S* I3 w  Q5 }7 b
  28.     {8 V$ H0 [# O) w  r& \; D
  29.         retry++;- ]+ C: X2 b" B1 T1 R& F' M% d* H& r
  30.         delay_us(1);
    4 S+ }* p8 ~! t' P# V3 n0 h
  31.     };
    & r  ?; W# n0 F
  32.     if(retry>=100)return 1;& L2 l$ J- ^! e1 m0 x7 I7 f+ Y. S
  33.     return 0;! o7 _- [) X7 m8 i! `7 y. z
  34. }7 ~4 e' d( \- n' d
  35. 4 ?# Y; |+ X8 L
  36. //从DHT11读取一个位
    . I, w9 n* G2 Z& S7 S4 m. w3 A
  37. //返回值:1/0. ~& S  `/ f( |7 d
  38. u8 DHT11_Read_Bit(void)
    ) t) N$ R: S$ [5 J4 Q5 t/ a% t/ ~2 k
  39. {
    , v% ?2 ~& r- \
  40.     u8 retry=0;1 x% z4 ]* C, p: W  x
  41.     while(DHT11_DQ_IN&&retry<100)//等待变为低电平
    ( n$ I4 I/ I1 D9 H( _
  42.     {
    + c) ]9 p$ u. U5 z$ u
  43.         retry++;
    - l6 P3 ]2 `' S9 g; v) ^8 y* q' n
  44.         delay_us(1);
    2 C, \% L: l1 E" h
  45.     }% P2 m7 ?' ]8 {
  46.     retry=0;1 q" O5 O% J1 X4 L. x& j
  47.     while(!DHT11_DQ_IN&&retry<100)//等待变高电平
    " f6 x5 L3 c9 M3 y+ f
  48.     {
    * S0 I, l9 X; M; d% A  N# X) \
  49.         retry++;
    - s( X2 {. t" C& L  h& D( @$ f
  50.         delay_us(1);
    : E+ I$ f8 ]' d  M
  51.     }+ f" Y% s' z. y8 z  k0 [  ]! h
  52.     delay_us(40);//等待40us" G+ I8 S1 l; V9 z
  53.     if(DHT11_DQ_IN)return 1;
    " J4 S  x/ i# P( ]: f
  54.     else return 0;
    6 `; p- _8 |1 l
  55. }7 V* N5 x, F, `4 O

  56. 4 b2 p7 j6 R# T2 d& K) d
  57. //从DHT11读取一个字节
    7 n' M: V2 \, ]( L2 r& J- E! x
  58. //返回值:读到的数据! Z4 g* r7 c! |7 z- u; z
  59. u8 DHT11_Read_Byte(void)
    9 Q9 ~! q2 m7 j6 ~
  60. {
    - S* V3 e# X9 ~/ r* }* }, u$ ^- P
  61.     u8 i,dat;
    & V% l9 i- O5 F9 p' p
  62.     dat=0;* Q4 w3 `& N& V7 B7 K+ k3 J
  63.     for (i=0; i<8; i++)& c4 D. r  s' c4 A% U
  64.     {
    ! `, B2 g- I8 X6 T3 h1 @
  65.         dat<<=1;$ {3 e2 x' A& t7 k
  66.         dat|=DHT11_Read_Bit();
    8 ~  h: m: C. [5 U, O% @" @
  67.     }
    4 [1 f4 L2 A5 t; P+ d5 l: z
  68.     return dat;# _, m5 q& |7 k1 s( ~& x$ q
  69. }& `1 p5 |& w  Y2 A

  70. " m  |. o9 s9 ^5 j" z! x
  71. //从DHT11读取一次数据- x% V0 G6 t# `# y- d
  72. //temp:温度值(范围:0~50°)
    6 y# Z' u. [$ m( F. B5 n4 P- q; H
  73. //humi:湿度值(范围:20%~90%)7 P7 |6 ]3 {$ C" [3 o% {3 Q
  74. //返回值:0,正常;1,读取失败
    ' z. F7 X% d- Z) \
  75. u8 DHT11_Read_Data(u8 *temp,u8 *humi)
    0 B& v0 [8 k; C: I" y5 L
  76. {
    + A/ _1 F7 g) _7 h' x& m
  77.     u8 buf[5];
    + P7 f# O+ V$ k3 h- n
  78.     u8 i;, D5 `; @  m9 p- O& e# l9 d" K9 Z. }
  79.     DHT11_Rst();
    ( a2 S+ e. M9 P, |9 Z$ ]
  80.     if(DHT11_Check()==0)
    2 p3 N6 m3 f: e+ L
  81.     {
    , T8 y2 }9 K7 L/ ~9 F, A
  82.         for(i=0; i<5; i++) //读取40位数据+ J2 u1 ?. {% P" M3 F$ x3 W
  83.         {
    * k; n- t" x( J  I2 |$ |
  84.             buf<i>=DHT11_Read_Byte();
    3 u2 K; B7 {, k: Q) w
  85.         }# f+ t2 x4 ?: p+ m/ S' b" s7 x
  86.         if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])) w! O+ |( u# ?! a1 p. e
  87.         {  m' J5 ^. q) l3 C4 i0 X
  88.             *humi=buf[0];  K! C) j! p$ i- @/ o: V
  89.             *temp=buf[2];
    " N1 w7 @, Z8 ~# i/ X2 V
  90.         }
    - I- a3 P9 n7 A6 g' W9 b) K
  91.     } else return 1;/ R5 `+ }: t/ n. Q3 e% {: ?! s
  92.     return 0;
    . I" `  S# u5 A. n/ g0 i' Z: r, I: E
  93. }  `5 C7 P, @. ]
  94. 6 ]+ F6 _' J# f
  95. u8 DHT11_Read_Data_Float(float *temp,float *humi)" k5 G! H! p- z, f
  96. {
    1 x5 V! M% Z0 B
  97.     u8 buf[5];" G" L9 t1 z( P; O
  98.     u8 i;$ Q7 g( h: q0 z
  99.     DHT11_Rst();$ l, W# l5 e( Q$ @9 F, ^2 l& a
  100.     if(DHT11_Check()==0)/ l4 \1 t* [1 [4 G% D  e& o8 N
  101.     {( W1 w* W2 _" S" w( m* {
  102.         for(i=0; i<5; i++) //读取40位数据
    ) C$ }8 D/ @, {$ k7 N; |
  103.         {
    2 n) X) D$ F) }9 B4 I0 j  G
  104.             buf<i>=DHT11_Read_Byte();
    ) A4 o0 t) x! S- l/ O" n) t5 i
  105.         }
    ! C' y/ |0 M7 v2 q& R4 T/ M6 e) L7 \
  106.         if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
    " \$ T1 y: N5 o' a& a+ R6 f
  107.         {6 ?' {5 C( ~2 X- `: W
  108.                         *humi=((buf[0] << 8) + buf[1]) / 10.0;
    5 F6 @5 T; O5 b! N* z& D
  109.                         *temp=((buf[2] << 8) + buf[3]) / 10.0;
    4 `1 H* |' t" s6 I( n- ^9 g
  110.         }
    ) o; v. L% n2 I! S2 w& [: o0 u
  111.     } else return 1;7 n3 W( t, w. H' O  A) E
  112.     return 0;
    9 s# [# K( r9 E- k
  113. }
    : r- h' e" s* J8 w& z$ W$ b% C2 n2 ~

  114. - B5 ~* n, r+ |$ A: V; x
  115. //初始化DHT11的IO口 DQ 同时检测DHT11的存在5 T7 k8 R7 C1 r% z! C
  116. //返回1:不存在% ^* V) b6 r8 n; d# J5 v* h
  117. //返回0:存在
    8 F( D! G+ }% e$ g3 `
  118. u8 DHT11_Init(void). A2 [# G# h" ?5 e  u
  119. {: ^. O' |% O5 D+ O- w% x
  120.     u8 ret = 1;0 H. Z/ H! Y" E! j" h* Y2 `
  121.     DHT11_Rst();  //复位DHT11
    ' Y6 K9 V1 ]$ n: V& a& _
  122.     ret = DHT11_Check();3 v4 h& R- r( W6 L0 d
  123.     printf("dht11 init %s. \r\n", ret == 0 ? "ok" : "failed");/ Y8 t5 o5 i' E# U
  124.     return ret;" O4 O/ o; G% [4 H
  125. }</i></i>
复制代码
' B# Z- v/ F0 {  p$ A' I
赞 收藏 评论0 发布时间:2022-4-12 10:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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