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

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

[复制链接]
STMCU小助手 发布时间:2022-4-12 10:00
sys.h: @) J2 w5 p3 m! x* X4 w
  1. #ifndef _SYS_H_
    ! l, w9 r) Y( I/ p; K" V' A
  2. #define _SYS_H_( m: h: u8 a, U9 H3 e3 D7 B2 E

  3. * j4 ^6 F. n: V8 {
  4. #include "main.h"
    2 S! P( a1 E6 o4 B& k! h
  5. & D# H% ^2 @& |/ X5 ~, X2 L% x. ?
  6. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
    $ d/ {# G  j8 P9 W
  7. #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
    5 R6 G' t( P5 D
  8. #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
    * B' B  c$ t- N  c$ C6 Z1 n
  9. 2 S; Y4 U# v1 Q9 u, i7 Q# E
  10. #define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 1 w- ]# ^1 r8 d, `
  11. #define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C - s- G4 {, p; r8 g. c' [
  12. #define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C
    6 g. {" @" C9 S  G
  13. #define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C & _! Q3 P& v5 t' D
  14. #define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 5 k9 b# l8 t/ P6 A0 g4 a* s
  15. #define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C   
    9 c( h* q* k  I- C# Q; R  X
  16. #define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C   
    4 t3 f6 F* ^  O& ?# i6 K7 F; z) _
  17. & O  A. \% J- x( F, a8 A
  18. #define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808
    . A0 d# w% M, v
  19. #define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 7 q& D0 R. B6 y2 ?+ z
  20. #define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008
    * N  c; A% {; {6 x7 c
  21. #define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408
    . W0 d- f0 M3 x( q0 b1 G0 N
  22. #define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808
    % [& S% x2 b  U* C0 o: S
  23. #define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08
    6 T* U8 J5 X, P4 w7 R
  24. #define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08
    6 p9 A3 e, H- l# F4 k  ?) a
  25. / c% v* e% ?0 \+ G& _( ^/ r
  26. #define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //4 \: s( c- f" Z4 Q
  27. #define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //
    ' V9 @) n6 ^% d* K1 ?
  28. : H- d# R7 G( L  S
  29. #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //
    6 B& S8 \* u% R5 X  i1 \
  30. #define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //, {* X2 t7 \) m( W
  31. , v2 |; H8 l4 F/ L2 k
  32. #define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //
    1 P( [$ I- q$ u& q+ G# y7 R
  33. #define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //: N) h+ @# l" P# d) V( V

  34. 1 \9 o1 Z& v# i2 A$ P
  35. #define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //, }% \0 t" h9 M  X0 w5 H& m% D
  36. #define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //
    1 L% F% U, P4 a" y5 u3 o" ?
  37. ' r1 X( v, s; g! R4 I
  38. #define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //
    ! N2 U$ a6 l% V* {! g6 T9 N; ~
  39. #define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //
    . f% Y$ Z. X' I. i9 l! I
  40. . U3 V4 }+ t1 P- H
  41. #define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //
    $ a( Z( U0 n" Q/ J" `  v0 R
  42. #define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //
    # n2 d, O3 x, O$ U8 X9 p2 ]7 }

  43. 4 U8 L1 G* \( y& V
  44. #define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //
    * W1 T& w$ H% O6 P5 ~" h: a- F$ c* P
  45. #define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //
    ! M6 x3 H  P+ [
  46. #endif
复制代码

; @1 Z3 D7 T6 T% T' [1 odht11.h& F+ m& R1 a* \: c) z- a$ n
  1. #ifndef __DHT11_H
    ( S. ]& ^4 a% C: I. A
  2. #define __DHT11_H
    $ T5 M) }5 B4 Z: D

  3. 5 H* h9 [" K& N4 z4 n3 q
  4. #include "main.h"( a  M2 \( l3 p7 y
  5. #include "sys.h"
    ( H" b& \2 V$ r3 V
  6. / E8 F  R  d3 o1 c
  7. typedef uint8_t u8;
    5 p- f6 ]7 ~8 K) J! t1 {
  8. typedef uint16_t u16;
    4 d$ @6 I% ]$ `: _( A3 u
  9. typedef uint32_t u32;
    5 t5 b) a. X8 I* e
  10. 8 e% B0 Q6 |# D- t( B- M2 s. ~
  11. //IO方向设置
    * U( m0 r9 T% H, c( w! e
  12. #define DHT11_IO_IN()  {IODHT22_GPIO_Port->CRH &= 0xFFFFF0FF;        IODHT22_GPIO_Port->CRH |= 8 << 8;}        // PC10 IN  MODE
    ) @/ e4 u8 Y/ r# A* ]  H
  13. #define DHT11_IO_OUT() {IODHT22_GPIO_Port->CRH &= 0xFFFFF0FF;        IODHT22_GPIO_Port->CRH |= 3 << 8;}        // PC10 OUT MODE9 B! A# w, o. C0 m, v6 F
  14. 1 Z" ^7 a5 U' s# S" q: \
  15. IO操作函数
    8 q/ B9 x6 e8 K6 I
  16. #define        DHT11_DQ_OUT PCout(10) //数据端口        PC10
    - k2 f+ _- |5 m" F7 o' i/ |! i  B
  17. #define        DHT11_DQ_IN  PCin(10)  //数据端口        PC10
    / r' f: v& \& y) ]2 m( B

  18. + y* h! c! w3 w6 R
  19. u8 DHT11_Init(void);//初始化DHT11# P. {8 N, V  z) G! G
  20. u8 DHT11_Read_Data(u8 *temp, u8 *humi); //读取温湿度
    ; e# e$ `+ i$ a' v
  21. u8 DHT11_Read_Byte(void);//读出一个字节2 E0 i) W! W) X% M6 U
  22. u8 DHT11_Read_Bit(void);//读出一个位
    7 g. g; h) i2 o' H
  23. u8 DHT11_Check(void);//检测是否存在DHT11% ?# W4 I2 X, Q, {) S4 ?& t7 X
  24. void DHT11_Rst(void);//复位DHT11
    ( \2 x1 ]) _0 f3 ]
  25. u8 DHT11_Read_Data_Float(float *temp,float *humi);
    ; i4 V  P& C+ p# O* P/ D+ I1 Y# H
  26. 7 ~9 s& |/ n+ b: O( c
  27. #endif
复制代码
$ y' X, N0 d/ r9 }9 H
dht11.c7 `& A; ]! U3 i$ f& `- }2 W
  1. #include "dht11.h"
    - L8 w2 Y/ ^  P0 u) }
  2. 5 R3 C; x5 m: M) G
  3. //复位DHT11
    5 R* s% G) T- p0 Q! Q; d
  4. void DHT11_Rst(void)
    3 F- J* u- n2 @
  5. {
    & {1 q" I& P9 b& q; `  p. w
  6.     DHT11_IO_OUT();         //SET OUTPUT0 f9 f7 Z; ]6 k+ _& {* K
  7.     DHT11_DQ_OUT=0;         //拉低DQ2 B) @( L  I  ]- n/ `- n) {2 U$ p
  8.     delay_ms(20);            //拉低至少18ms,(DHT22 500us), ?, |! I$ |' Z
  9.     DHT11_DQ_OUT=1;         //DQ=18 R! V$ w: b. w. }/ h( B
  10.     delay_us(30);             //主机拉高20~40us1 }, f) p0 ^/ u- ^8 G$ \' o: d
  11. }' g+ u$ g! t8 P/ I9 K' }

  12. , l- Z4 U# X6 B/ B9 M
  13. //等待DHT11的回应" G4 ?: x4 \# s1 q
  14. //返回1:未检测到DHT11的存在8 L- d/ Q+ ^" Z9 Z
  15. //返回0:存在, ?8 r; ?' v+ a& K  G. {
  16. u8 DHT11_Check(void)
    - T3 k8 k- |5 ]1 @
  17. {
    8 z# n- o  G! [5 c& N2 z
  18.     u8 retry=0;
      n  a# Z6 T1 ~
  19.     DHT11_IO_IN();//SET INPUT
    4 Q* N& A- W9 E
  20.     while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us
    3 |# D! Z5 h# Q
  21.     {
    : d# G- S' o2 d
  22.         retry++;
    " l" r9 F" Q$ ]" F
  23.         delay_us(1);" G# M1 ~6 a" X" a
  24.     };2 o! \! o  t# h: L
  25.     if(retry>=100)return 1;
    7 p6 l9 l' u+ s- Y
  26.     else retry=0;
    ! a: ]0 o6 A7 c7 q# s% E* N3 S& e
  27.     while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us, b; y# c5 G$ X" y
  28.     {  c. {# J! l& _$ u& f& ^
  29.         retry++;8 s- _$ X3 h! M5 \8 G- p& I
  30.         delay_us(1);' e1 d- D* _7 l" @7 _  s
  31.     };
    # n" C0 Q7 I# J% [& u5 ~4 \
  32.     if(retry>=100)return 1;
    9 z; Q( a. ^# J: Q
  33.     return 0;
    ; b8 X- c; C* M: e" Z; t
  34. }
    ' j& I( b& U' Q* G! }) a
  35. $ r+ {, h: n; e% m
  36. //从DHT11读取一个位* S# S. n+ _+ E/ p  [% y. f
  37. //返回值:1/0
    8 n9 o0 N. F7 e! P
  38. u8 DHT11_Read_Bit(void)
    , b# b5 o2 ^4 ?  T
  39. {
    + _' S# H. ~* b0 n7 H/ o4 Q. v% ^
  40.     u8 retry=0;
    8 v2 X0 i$ Q" \) u
  41.     while(DHT11_DQ_IN&&retry<100)//等待变为低电平: H8 H9 g. O) ?' }* `! I$ ]# y* b6 `, G
  42.     {  I( G# J) E6 {, t/ l4 P
  43.         retry++;
    ) g) J4 k3 n# j! m. O
  44.         delay_us(1);) C0 a7 Z& w' y, b
  45.     }
    : M; v0 q  K5 L9 B8 t
  46.     retry=0;
    ' E" ~& D% N+ S- m. b
  47.     while(!DHT11_DQ_IN&&retry<100)//等待变高电平
    # W0 L  e# @, ?$ _; x3 x; J7 x
  48.     {) u! d3 U; q2 I
  49.         retry++;$ m1 u+ ?+ _# ~& F. `
  50.         delay_us(1);
    3 o- U: s, n: m4 Z6 o
  51.     }0 u. I/ ?+ F9 X$ j9 G& U8 B
  52.     delay_us(40);//等待40us
    5 t; q" u3 C: S/ [' k& R' B
  53.     if(DHT11_DQ_IN)return 1;* v5 t. v% a9 P/ O2 x" ?0 c
  54.     else return 0;9 D" @& M# |% I7 s4 ], R
  55. }( w, r( ~* _$ e. D- }7 W! H$ W

  56. 2 E! p! J# R* i: r; A. h
  57. //从DHT11读取一个字节: y% o+ Y( `, o* b9 p
  58. //返回值:读到的数据
    $ A: U; X- U; e
  59. u8 DHT11_Read_Byte(void)
    - ]5 F$ V7 [, r1 e
  60. {& i& }$ Q, A5 X9 v4 R& T
  61.     u8 i,dat;
    ( p' o4 q0 S2 U3 c
  62.     dat=0;
    $ \; N4 {- J! k
  63.     for (i=0; i<8; i++)
    " B: E% r# L# A+ U' \  P# {4 ~
  64.     {- _! |2 g" q! a  }- O- Y9 b, J0 Q. N
  65.         dat<<=1;" C' [2 o. V' x# q
  66.         dat|=DHT11_Read_Bit();: f, ^  ]" ?6 P7 S4 x2 ~
  67.     }
    3 w3 k. _4 }- y
  68.     return dat;
      j8 s8 o' [0 W# [$ B; T) [/ y
  69. }& Y: r4 v& D' O- H9 N7 I' t

  70. - \. n7 N, I, t) M
  71. //从DHT11读取一次数据  K1 [% b) Y' i( V
  72. //temp:温度值(范围:0~50°)
    1 O" t, p+ y/ o+ b5 |, a" P
  73. //humi:湿度值(范围:20%~90%)
    # V! Y3 B6 a. W+ T6 [
  74. //返回值:0,正常;1,读取失败5 W( J! N" h/ K+ p
  75. u8 DHT11_Read_Data(u8 *temp,u8 *humi)
    0 b8 T) H( S, m* w4 ]$ r4 R
  76. {1 }  \* v* S. f0 `+ G
  77.     u8 buf[5];
    - V" k3 D7 Q/ D% b$ K; G( U5 `$ C
  78.     u8 i;; k# c; q1 Z' ]
  79.     DHT11_Rst();
    % T  b2 K: e, G1 L
  80.     if(DHT11_Check()==0)
    # \7 T2 C) z% W- q3 m1 i
  81.     {; u+ Q3 f* Y) Y- ~8 }9 W
  82.         for(i=0; i<5; i++) //读取40位数据1 N$ Y. f  j1 c/ A! z
  83.         {
    ( }5 J5 D3 |% s3 }  w3 C2 D) g
  84.             buf<i>=DHT11_Read_Byte();( Y4 ]! @1 X  I
  85.         }
    , B( x5 t8 o  ^0 E3 S- G+ s
  86.         if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])1 ]7 }) m$ i3 ~- E' L5 f
  87.         {
    ' Y# G0 ]0 `# i) M5 x1 S
  88.             *humi=buf[0];9 }- V4 e, V, O0 k; v
  89.             *temp=buf[2];
    ; u; X1 r5 a; o4 I5 j
  90.         }
    + x+ J5 H9 y% N+ B5 ]
  91.     } else return 1;% ~8 `% v' _! k% b
  92.     return 0;
    ( `* _& B' `! {+ o$ d
  93. }/ s: t( ]" G* T5 r) K8 n" x

  94. 1 c4 @7 k5 T" @
  95. u8 DHT11_Read_Data_Float(float *temp,float *humi)" S3 u6 n, ]# G. F& L8 E# ]% v" c
  96. {; S) Y. \0 c9 E3 _1 O6 Q
  97.     u8 buf[5];$ K# {, T) n7 |( ^5 H$ }
  98.     u8 i;
    , G! z# y6 N- m! e5 ~: K& v; I
  99.     DHT11_Rst();( D: F" {: t# G) ?
  100.     if(DHT11_Check()==0)
      D. \7 }5 t5 L/ J( K
  101.     {" Y* |+ `* {* Z+ J% i+ n/ [
  102.         for(i=0; i<5; i++) //读取40位数据
    7 E; W6 K7 f: L" o
  103.         {# |. Q6 A3 W0 W; V% X5 U3 d
  104.             buf<i>=DHT11_Read_Byte();0 g& N. _) S/ I
  105.         }* N  G6 ^! Y" q
  106.         if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
    ' t& }6 F( Q* p' u
  107.         {+ M1 R1 H1 q1 f( h2 {3 f3 c  S
  108.                         *humi=((buf[0] << 8) + buf[1]) / 10.0;
    - t% I0 ~& w2 @' N/ [' g/ g
  109.                         *temp=((buf[2] << 8) + buf[3]) / 10.0;- [  ^1 E! t8 U: E
  110.         }
    2 E7 Z7 O% d! e5 V1 h! U
  111.     } else return 1;
    % O+ T9 L$ u! a5 }6 g2 r. b- v$ D
  112.     return 0;
    : R! W4 C4 v  \1 S$ z1 G
  113. }
    3 y0 w2 e* S9 b4 D5 f  N5 |
  114. ) w6 \" r' {- C2 s' D
  115. //初始化DHT11的IO口 DQ 同时检测DHT11的存在& x4 N0 f* c" p% o
  116. //返回1:不存在
    ! v2 m* d$ p1 Z9 ?" {- \, e/ X* L
  117. //返回0:存在
    ) T1 t8 \+ T5 w7 F' S& j0 H
  118. u8 DHT11_Init(void)
    - j# Q- L1 D! w# u7 r
  119. {
    0 m6 [# {5 f9 ?; X7 ]
  120.     u8 ret = 1;
    ( x+ g0 H$ z% B# S) ]
  121.     DHT11_Rst();  //复位DHT11
    , v: G& s2 C8 w# ?
  122.     ret = DHT11_Check();
    : k9 B9 h1 F. `2 \! K
  123.     printf("dht11 init %s. \r\n", ret == 0 ? "ok" : "failed");& Q& ]* c% V& f5 e
  124.     return ret;: W6 Q9 d4 M5 y+ R6 {( I- ]$ `
  125. }</i></i>
复制代码
  x. k: A$ g3 N" U: g- @
收藏 评论0 发布时间:2022-4-12 10:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版