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

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

[复制链接]
STMCU小助手 发布时间:2022-4-12 10:00
sys.h
- M- x7 C* t  D0 n$ r
  1. #ifndef _SYS_H_: K1 b& u/ W3 f7 ]! Z3 {# e
  2. #define _SYS_H_
    5 ?1 p) m/ V: i& E- U: I0 c5 ?" F
  3. 4 S" t; m, O# q$ Q5 M
  4. #include "main.h"
    , h8 }0 @/ b5 g
  5. - y$ h1 L9 j+ v/ ]% }
  6. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))# |3 l, R+ f, T+ S4 ~( |6 r- F6 n
  7. #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
    4 H) @+ Z# w, |8 I! ]
  8. #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
    4 g: b. |$ m, y4 e9 g
  9. ! t' }8 k2 p8 y* D( X0 ]
  10. #define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C ; m8 u9 m" i' O$ ]2 {) n+ M
  11. #define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C : n; V5 g8 H1 K9 Y& e
  12. #define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C
    - {5 c; L% }0 G# e: g" R
  13. #define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C , F3 V7 W* Z* {& {* E/ m
  14. #define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 5 b+ \0 g; E* a
  15. #define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C   
    ! }* Q5 N) @* }, n; t* r3 H8 x  ?
  16. #define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C   
    & h* b( L  i& k

  17. : f) V. s* ^0 l1 L; V3 |- f
  18. #define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 # t/ v8 e2 ~& F& e% t6 r9 ~
  19. #define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 4 Y8 o& N# ?, L2 C; U; ^$ N1 \) {  n
  20. #define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 / P2 A- U* d/ Q6 M( X1 n7 N* Z
  21. #define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 ' q! o/ F) L0 b) O
  22. #define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 " Z$ E4 |5 ?& q( }$ P# W' k; C
  23. #define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08
    : R( \+ ?3 y* r- G' H$ [- r
  24. #define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08
    1 ]# F- v' a( i  A" I, m. V

  25. 7 @0 e3 n6 {8 C1 \0 j, e& u
  26. #define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //
    + `5 b8 F0 @6 r: M7 G# T+ L7 y
  27. #define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //
    4 q% N3 n8 C5 M; t) X) X
  28. & |3 E- [/ T' U& h/ M/ X5 ?  p# t
  29. #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //0 ]0 C) Z! L  i3 i
  30. #define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //
    7 P7 {4 B: P0 V& H

  31. 2 B' a2 V6 U6 @: S! {
  32. #define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //  ?$ w$ s/ A4 U% b3 Q* T7 q
  33. #define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //9 Z* |' P% D0 h
  34. 0 o$ O) x& j5 y
  35. #define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //$ @$ i) o5 a$ N$ m
  36. #define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //; u$ W7 L& b* q  n" b4 ^; ]+ q% D
  37. / U* Z8 r2 I+ ^' x
  38. #define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //
    . C' J. c2 j! t5 X# O$ H+ c& f
  39. #define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //
    ( L/ z6 I; c7 ]6 y
  40. 4 ~$ Y; K7 m- Z7 A. M
  41. #define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //
    1 P' S1 h  g9 _+ ]; s0 {% B
  42. #define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //. ^; J* j- M3 Q& W% O6 s

  43. * N6 C4 Y- P9 O1 n, i  ~+ m1 d
  44. #define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //
    7 @/ v3 V& l1 X8 i; A& G4 I2 T
  45. #define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //
    ! ~/ Z- x; Z7 k' R- Q" v" L6 o
  46. #endif
复制代码
! z: [" l+ b" h! V
dht11.h/ I& n' w; C6 k
  1. #ifndef __DHT11_H, N% l/ `0 X& z" E
  2. #define __DHT11_H. k* F8 ^) Z1 Z9 n$ c) ^$ ~
  3. * X0 I% Y( _6 {/ Z# y7 P4 f$ a% h3 J
  4. #include "main.h"
    5 e9 I/ k* n0 P; a
  5. #include "sys.h"6 ~5 K6 K/ ~# n. [
  6. / l1 V. a$ }8 ]$ a3 f( W9 L, `
  7. typedef uint8_t u8;
    # Y' G4 y5 _2 B3 H
  8. typedef uint16_t u16;5 @8 v' g4 @9 ]
  9. typedef uint32_t u32;
    3 e6 r9 f0 y5 Y  B' W

  10. $ w0 c4 R, C' {( E
  11. //IO方向设置
    . @9 ^$ C) L2 N3 G3 c$ T8 F$ Y
  12. #define DHT11_IO_IN()  {IODHT22_GPIO_Port->CRH &= 0xFFFFF0FF;        IODHT22_GPIO_Port->CRH |= 8 << 8;}        // PC10 IN  MODE5 s1 m8 w1 t  n3 B7 v
  13. #define DHT11_IO_OUT() {IODHT22_GPIO_Port->CRH &= 0xFFFFF0FF;        IODHT22_GPIO_Port->CRH |= 3 << 8;}        // PC10 OUT MODE: l: ?2 C, u3 [, I

  14. 4 B/ Y2 I' M: m9 ?+ g7 r
  15. IO操作函数
    % d: t) y4 }" c$ w  u2 g7 z3 \
  16. #define        DHT11_DQ_OUT PCout(10) //数据端口        PC10
    . B$ Q( j" o7 e9 h- B. T! j
  17. #define        DHT11_DQ_IN  PCin(10)  //数据端口        PC10
    . w8 w( a& U. I
  18. & r/ b2 P: n0 B1 v+ u/ k4 Y! @
  19. u8 DHT11_Init(void);//初始化DHT11
    , `$ S' p5 c+ x; u
  20. u8 DHT11_Read_Data(u8 *temp, u8 *humi); //读取温湿度, x0 f. O6 k7 B' {0 u  l
  21. u8 DHT11_Read_Byte(void);//读出一个字节. {2 _0 ?6 c+ J
  22. u8 DHT11_Read_Bit(void);//读出一个位6 C5 p7 @7 g- n
  23. u8 DHT11_Check(void);//检测是否存在DHT11
    ! L: Z$ R% c: J, Q* u: N$ u
  24. void DHT11_Rst(void);//复位DHT11/ R+ ^3 u# O1 a' B
  25. u8 DHT11_Read_Data_Float(float *temp,float *humi);. q/ j+ t+ H3 Q9 ?* t; Q  w

  26. 9 X1 H; o4 O0 |8 R& \2 `3 u
  27. #endif
复制代码

% |. D8 e  Z3 kdht11.c
; j9 D7 w9 x8 f7 M& H9 K6 n
  1. #include "dht11.h"
    7 G, `' A+ k3 w  k9 y9 d

  2. 5 ]& H" v( f: d  W' I7 m3 Y0 m+ S
  3. //复位DHT11! @3 p" Q( q+ K
  4. void DHT11_Rst(void)
    , ^; e0 ]) O, i: I) l% _; n
  5. {
    # G6 g! B$ w( I
  6.     DHT11_IO_OUT();         //SET OUTPUT' U. V. d7 z* \2 v- a; ]
  7.     DHT11_DQ_OUT=0;         //拉低DQ2 O. I: t& N2 k* H/ \+ @3 k
  8.     delay_ms(20);            //拉低至少18ms,(DHT22 500us)
    9 B, g' T2 J, H, c
  9.     DHT11_DQ_OUT=1;         //DQ=16 i! c; M2 ^7 k9 |
  10.     delay_us(30);             //主机拉高20~40us7 Y+ _8 A7 |% x5 m* v, t
  11. }
    : v4 x- J0 l4 i: a. i- B* T' y
  12. ( H  r' `7 _0 j0 u
  13. //等待DHT11的回应
    % ?8 g3 O9 s0 e6 E" H* m# s
  14. //返回1:未检测到DHT11的存在
    ! q0 H5 W/ ?. E9 ^4 X" ]% s
  15. //返回0:存在( Z3 F* G' G' l- d: Z4 t$ h  t* T
  16. u8 DHT11_Check(void)
    ' ^$ {  |3 G; Z# R& ?* a' t% }/ g
  17. {
    ' {6 D# N9 x( ]( R0 M
  18.     u8 retry=0;
      f- B3 E- k' L
  19.     DHT11_IO_IN();//SET INPUT# I1 e. @9 u5 b4 }
  20.     while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us9 n5 B, I# F) Z- W) W
  21.     {
    : b0 o5 w1 q2 \- q7 w" _, E* v8 Z) e
  22.         retry++;
    / B6 P( d/ C* r: L
  23.         delay_us(1);2 n( t1 o4 ^3 T3 [
  24.     };
    + ~- f8 T4 s" ^0 t1 J: W
  25.     if(retry>=100)return 1;5 a. ~: \% |$ J
  26.     else retry=0;5 s2 S+ j! n. Z4 v# N
  27.     while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us) u7 A; Q3 L* C" Z. u% b
  28.     {
    5 N5 [+ j; [  c9 b( h
  29.         retry++;" g" u6 H8 M3 |. `/ I
  30.         delay_us(1);) A; E: G6 i( l/ L" ?( }6 p5 H
  31.     };4 r' L; T, {# s4 c1 P' G$ E
  32.     if(retry>=100)return 1;2 x* j1 @0 n- d; p3 D) I
  33.     return 0;4 T9 V1 t! U6 k7 q8 ^' X( r
  34. }
    : B2 y" M6 T/ H" f! G

  35. : B  z5 [( ^, B8 m
  36. //从DHT11读取一个位8 w6 u4 ]& a4 u
  37. //返回值:1/0
    ( W7 E' B3 j/ E
  38. u8 DHT11_Read_Bit(void)9 ?2 J# Z( I' i
  39. {
    , V3 y% j3 H' q
  40.     u8 retry=0;
    1 D5 O4 G! ]. q0 c: s' T
  41.     while(DHT11_DQ_IN&&retry<100)//等待变为低电平
    6 M* {, a4 L6 ~# J7 B
  42.     {' D" Y. I' H3 V  X
  43.         retry++;
    ! ~8 N  d2 ]1 t4 F9 ]4 E
  44.         delay_us(1);. i" ?5 t, Q. m6 w6 f. g5 Q
  45.     }
    / |9 Z2 g8 F/ I1 C) d* E8 v0 W
  46.     retry=0;
    6 o* Q2 \. ?* q1 C9 ~" d5 r2 E
  47.     while(!DHT11_DQ_IN&&retry<100)//等待变高电平
    $ e6 Z. S) \3 G* v* ]8 U9 T
  48.     {
    , n. q* F$ f: T0 n2 S9 E' I
  49.         retry++;" Q$ C0 b% o) y4 G5 c3 A
  50.         delay_us(1);
    2 j( {# w! M: G. |2 n9 x
  51.     }* q8 a0 H6 c" D$ |: L; x' S
  52.     delay_us(40);//等待40us/ r9 u1 [) A, b+ {
  53.     if(DHT11_DQ_IN)return 1;
    + ^1 t" ]( _# ?3 ?' n1 x
  54.     else return 0;
    % Z; L- _7 c% y0 `+ ~8 A  w
  55. }
    , X" U9 B: b* L' b0 Z

  56. - j5 [5 h+ ^) L( u. ?
  57. //从DHT11读取一个字节
    4 ^' `& N, N& L
  58. //返回值:读到的数据
    $ ~, w& Z! @9 o4 P" M
  59. u8 DHT11_Read_Byte(void)6 s6 K! j' b8 e8 L
  60. {
    0 i; h+ |6 E! w# R1 @: T
  61.     u8 i,dat;2 d6 b3 z" i  B1 Y+ Y& \1 g- [
  62.     dat=0;
    : @4 q" F$ z7 E# O8 F
  63.     for (i=0; i<8; i++)
    % `! ?6 H! r* \* `: I) i% c9 ?( b
  64.     {0 @, K5 d7 s3 X" F7 ^( ~- w" F
  65.         dat<<=1;4 S2 d6 ?. Y* m  E0 ~, }
  66.         dat|=DHT11_Read_Bit();  ?4 r0 a7 Y9 k! G  o
  67.     }  N7 r: X9 F) R$ I- z8 H
  68.     return dat;) r3 L6 u; F9 e* V' V) W5 |* n$ T# t' W
  69. }$ C' c' j( t+ |5 I/ u3 I
  70. , A  o" ^3 N4 v) ^- L" [' d
  71. //从DHT11读取一次数据; W2 u1 V! [/ u7 N
  72. //temp:温度值(范围:0~50°)  C. j) i9 [, k; _$ W
  73. //humi:湿度值(范围:20%~90%)5 B7 V/ D; a5 k" u7 x+ Q4 L9 X5 x
  74. //返回值:0,正常;1,读取失败. `; D/ `4 f( {3 ~
  75. u8 DHT11_Read_Data(u8 *temp,u8 *humi)2 v! m( _: _' U1 q, t' [
  76. {. N( f/ b9 ^1 Y* G- t
  77.     u8 buf[5];6 A3 v! t5 Q3 u5 R2 U7 s8 T. g& P5 w
  78.     u8 i;4 Y# L  K4 a/ h* ^
  79.     DHT11_Rst();
    4 [* T& r; G; k
  80.     if(DHT11_Check()==0)  G& F6 A2 t1 p# y) x
  81.     {
    0 N7 m! J  p( X) B
  82.         for(i=0; i<5; i++) //读取40位数据
    2 V3 Y" ]! `$ i  v* m; u9 t& d& b
  83.         {
    9 B! q7 X5 h' C- M- P+ S3 j
  84.             buf<i>=DHT11_Read_Byte();
    ) A* ^* t  f0 `0 h- D( P8 a4 s) a
  85.         }
    , W& o5 V/ `, t4 O/ U5 w* F
  86.         if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
    4 _/ u2 v$ [  `, V9 J
  87.         {4 e. z9 E& F$ \: d! g1 r& J
  88.             *humi=buf[0];2 C4 C2 t- _( Z5 p" t/ L
  89.             *temp=buf[2];
    ; p$ |, B6 G2 N, Q; o
  90.         }" y* C2 _* H( p1 O2 s
  91.     } else return 1;
    & z3 d  z4 ^9 s# W; E) ?
  92.     return 0;7 R* \* v4 @4 }2 G% J
  93. }4 m" s' k; o2 Z5 i- I& c' p2 t; p
  94. # K# U) J- ?5 L3 ^0 G" l
  95. u8 DHT11_Read_Data_Float(float *temp,float *humi)" C, Q* e; U; r
  96. {
    ( H( H/ F0 C" j8 ^
  97.     u8 buf[5];' T1 m. Y* }* \- k, X( c; h$ ?7 `
  98.     u8 i;" J& B/ o  }( Y( X1 w. j
  99.     DHT11_Rst();
      R+ q$ x7 `" C2 H
  100.     if(DHT11_Check()==0)4 R; U* e5 x8 @4 ~: a; `5 z( c3 b
  101.     {$ n) c# R2 x1 h1 R1 E
  102.         for(i=0; i<5; i++) //读取40位数据
    " O# l+ p% Y( x- I# J# K+ K
  103.         {" i5 i. L6 w5 S
  104.             buf<i>=DHT11_Read_Byte();
    7 [3 k8 S% d8 j" A$ P) K  V
  105.         }
    5 ^$ W: \1 D- t
  106.         if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])" a2 d0 `9 m3 d+ g
  107.         {6 |2 B4 s% g* ~" U  i) Q/ ~# E
  108.                         *humi=((buf[0] << 8) + buf[1]) / 10.0;5 @2 W- l  B. h/ O4 v2 G' g( |1 k& z
  109.                         *temp=((buf[2] << 8) + buf[3]) / 10.0;
    % u* n* s9 ?. k# ]+ s0 ]
  110.         }" t* ~+ ]) }: n: S& H
  111.     } else return 1;% i' a: {2 ~% h: e
  112.     return 0;
    0 D  P2 W; o5 r" D  ]" p0 ~% h3 A
  113. }/ L/ M( T8 w9 z& k# L4 g' n, q
  114. & b( h3 r: k/ d4 B9 k4 B2 ]; f: X
  115. //初始化DHT11的IO口 DQ 同时检测DHT11的存在
    ; i  w  l7 n& V7 ]: Y
  116. //返回1:不存在: W# N9 b% q$ f" m6 I
  117. //返回0:存在; c7 g$ b$ i6 X
  118. u8 DHT11_Init(void)
    - @; n& [% M) r2 W) ^
  119. {
      ?$ ]8 v8 Z; l) a; U/ p! U5 x
  120.     u8 ret = 1;8 Y( u$ x( Q. `0 F! }
  121.     DHT11_Rst();  //复位DHT11
    * o+ C; \5 H( ~$ D
  122.     ret = DHT11_Check();
    ; s1 j% l$ f& ^/ R7 m! f
  123.     printf("dht11 init %s. \r\n", ret == 0 ? "ok" : "failed");
    2 E  C" Y6 x  \" [+ @
  124.     return ret;' i; r  m) z! s! Z7 }
  125. }</i></i>
复制代码
, x% }* y- B% n  w6 T
收藏 评论0 发布时间:2022-4-12 10:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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