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

【经验分享】基于STM32F103C8T6(HAL库)的HC-SR501红外人体传感及HC-SR04超声波测距

[复制链接]
STMCU小助手 发布时间:2022-4-15 10:00
前言3 }& k1 a& a$ K1 e
我在上一篇文章中驱动了HC-SR501红外人体传感模块,但在测试过程中发现,这个模块的热释电探头过于灵敏了,甚至有的时候往上哈气,会因为检测到类似于人体的温度而误判为感应到人体,所以为了减少误判概率,我打算再添加一个测距模块,在红外感应到人体时,再次判断人体与传感器的距离,在满足预设的距离范围时,才确定有人体接近,进行后续操作。
/ D& @# R* [, _4 Z. A一、模块简介
7 r' k) S2 d; ?HC-SR501红外人体感应模块资料介绍:
6 `2 x) }7 K, J探究人体红外传感器HC-SR501
8 f( X0 E3 Y2 W1 [; R& i# w
+ S* O4 j0 J- v* gHC-SR04超声波测距模块资料介绍:7 y" N: f7 u; W5 u& Z2 }, s
* a. i! A$ E  ?/ m' t
[}NY0UME6`THJ~NGH(UFEM5.png
2 W/ @7 U; x% M0 o5 s2 G* c. ~5 R! ~0 ?+ V
P93W`1KJ@3I1B%9T~XHA%3M.png * _1 v+ b2 W- G2 C8 o0 J- x

! `) G! O, b2 E工作原理:4 h) e4 M2 }% Q& _& Z

( }/ G, O2 X2 Z$ z! | 2440fa92274644939b0de5e59ef1852b.png 2 L" {! f1 M/ F7 M* s: U( r

( E- e6 _3 S4 Q9 b: T6 }8 [ TTPZ0O8GJDMQZXWX}%P2A.png
; u: d- D7 x& ^( F! F" A8 M. b5 ^( m5 ?5 x
简而言之:
/ g& Z' Z' l4 ~: t. p+ Z给Trig一个10μS以上的高电平,模块开始工作,模块内自动发送八个40khz方波,并自主检测是否有电波返回。此时需要检测Echo处的电平,当为高电平的时候记一个时间;当Echo出为低电平的时候再记一个时间,这两个时间的差就是高电平持续的时间,最后用测距公式进行计算。
; ^, l3 e6 Z/ h, l8 I# d6 G  T0 y& m0 k0 \
二、配置CubeMX  q/ M& j6 t$ ?0 K% q
1、新建工程;
, [5 Q2 I& C% u3 B" c2、配置时钟源,在RCC里面的HSE配置的是晶振时钟;
8 k$ p8 n3 l* r3、配置程序烧录引脚SYS为SWD模式;# l* @) ^. i* {) n# Y/ R5 B5 U9 [
4、配置GPIO输出口,配置一个LED灯(我的板子是PC13),起到检测到人体时的指示作用;
& b, e- ?8 N+ o5、配置GPIO输入口,用来读取HC-SR501模块的输出电平,我选的是PA1口;
" S# G. Q: x& R6、配置GPIO输入口,用来检测HC-SR04超声波测距模块的回响信号输出,我选择PB5口,命名为HC_SR04_Echo_Pin;1 r5 p( \" A8 Z7 ^, R
7、配置GPIO输出口,用来触发HC-SR04超声波测距模块,我选择PB4口,命名为HC_SR04_Trig_Pin;
$ K& Y) _+ [* J9 z, C8、使能定时器,用来实现微秒延时,和测量HC-SR04模块高电平时间,我选择TIM2,并使能TIM2中断;: S2 X* k) _9 |2 T" |1 @; g
& ^8 s% Y+ M+ Q
Y}$I[3U85M8EJX0`TSX}Q@P.png 2 d! b4 C5 q5 l8 @8 s8 ]

* H5 Y9 ~* w' {6 l3 b; t* \# uTIM2挂载在APB1,时钟来源频率为36MHz,故取预分频系数PSC=36-1,计数周期Counter设为60000-1。即此时定时器频率为36M/36=1MHz,每60ms进一次中断,60000μs对应实际测距范围大概为10m,远远超过我的需求。
" g, G8 a1 x, R/ J6 Z0 N3 T" O  `
$ X& S# F. j) D; b8 _& X CP1WI%N(~F}{56Z8OZ{NHN4.png , X: \& n! o' C; x) }% ?' H
/ S$ t# d* x6 q, u" p: p
14c2aefe04d5410b89a5300226b73aa6.png
6 Q6 |" `6 Q4 L) m6 N, L& v1 w$ b" V6 s& B
9、配置串口收发引脚;
# c6 E; ^/ @9 x2 m! [2 M; e10、配置时钟树,我还是开到最高的72MHz;
8 ~* N3 T& P- a' J* g11、进行项目设置,最后生成代码,CubeMX部分就大功告成了9 X. j% T% v& l  j) m
, \% }0 u2 z* B( }
B4M6VI[W3NYH~IN2P13@NCA.png 8 t5 m% ^& [1 _5 @2 b* `+ S% w

% J- a$ F# K/ k; x三、硬件连线部分* _  L: z, _9 @, E
CH340 ↔ STM32F103C8T6最小系统板:
$ K& @: x+ N% L( I. ]' s TX    ↔        RX
" C' ^3 F6 ]- }, R$ j RX    ↔        TX
/ \0 l) N$ L  I+ k/ O8 u9 W5 P! o6 h! ~
DAP-LINK ↔ STM32F103C8T6最小系统板1 f9 P* }+ E$ n& b
  3.3V    ↔         VCC$ Y& a6 [! l0 T! d  i4 p. Y# U, V
  GND    ↔         GND' w# o* V  p) d) L# T
  SWIO   ↔         SWIO- t- X$ Z( O& l/ W" I* o
 SWCLK  ↔        SWCLK' s. @# d! ~  z7 }. a

- F4 f" Y; W! [( i7 FHC-SR501模块 ↔ STM32F103C8T6最小系统板
& r7 H3 h% ^- ?  k    OUT      ↔           PA1
% k' f: _  b; U/ B8 K/ x    GND      ↔           GND% y& \3 i" @) z$ |- w9 L5 v

+ C- Y5 b8 ]6 y( G4 T) kHC-SR501模块 ↔ DAP-LINK (这里注意模块供电范围为4.5V-20V,用3.3V无法驱动)* h# S( I2 V3 y
     VCC     ↔    5V4 a8 Y5 e6 j% b7 _; q# U+ m
  [6 S! V5 Z3 U" ^
HC-SR04模块   ↔  CH340' k8 L( j* h: ^5 Q* Y
     VCC      ↔    5V
1 \% l- J$ ]+ V( F6 X9 \: u. |7 ~; z8 q
HC-SR04模块   ↔ STM32F103C8T6最小系统板/ w' {; h: T" \& }# ]/ \6 S
     Trig       ↔          PB42 b$ H9 ~$ b0 |. }
     Echo      ↔          PB57 b# }5 e( K0 ~- f& a' H
     GND      ↔          GND# e6 `) F) P2 ^$ {
  c/ a& K( h, S2 \
四、逻辑代码部分
% ~+ [& x8 S; A9 _- i代码框架是基于上一篇HC-SR501红外人体感应模块修改而成的,想要完整代码的话可以和上篇文章一起看。
8 q* x+ B; G: @  I' B
! ^% P  O5 q) ~( h; oHC_SR04.c
+ o! ]# w" d" t/ h7 d( t( [4 l
  1. #include "main.h", `, g9 ^8 [& t: U* [. Z% \
  2. #include "HC_SR04.h"6 e& |4 F! b) ~; @# S" u% v
  3. #include "stm32f1xx_hal.h"
    . ~) m2 S- H- b. C6 e
  4. #include "stm32f1xx_it.h"
    3 ~+ a2 |# a/ W% \& n1 k) x- E

  5. / k; C2 @5 b& u  B8 t6 V; K
  6. static float distance_result;
    + r" K9 X3 \9 i7 m& a2 K
  7. /*% Q, ?( q' h4 I& r6 K1 M0 c
  8. *********************************************************
    & ]# t! J9 c1 p& I7 I
  9. 函数原型:void Delay_us(uint16_t time): h& _# ~9 |+ T' G0 }: g
  10. 函数输入:无符号整形. ~: h! ^- a, U) i( D/ \
  11. 函数输出:无8 g- ^& H' p2 ?1 ]% {  S
  12. 函数功能:利用定时器实现微秒级延时
    + y/ k3 @% w; j% m' M) E
  13. *********************************************************
    * ]7 W* _+ ]. b# j! a/ P/ @0 N. M
  14. */
    $ |: C. Q( i! H7 `. X
  15. void Delay_us(uint16_t time)% e2 ^7 i& Y* w- ^' X
  16. {; z; K: V1 ~8 j, Y+ M2 l% H0 X- B
  17.         uint16_t a1=TIM2->CNT;
    3 i6 M0 w5 N' q- W8 `
  18.         while(TIM2->CNT-a1<time);
    8 d/ }& r8 i8 C
  19. }
    & Q; b4 q( @/ \' z
  20. /*3 D: s& V- i4 s5 d7 e" H) E( g; h
  21. *********************************************************( m3 v7 m8 H. A9 G9 c
  22. 函数原型:void HC_SR04_startrange(void)
    7 P  w. b8 R/ N: |6 t1 E% Y7 j
  23. 函数输入:无+ q, H8 L8 C& s7 d
  24. 函数输出:无
    & }" V4 V, Q; l
  25. 函数功能:从trig引脚生成一个不小于10us的高电平触发测距,触发后模块自动产生8个40kHz方波,自动检测是否有信号返回7 U) s9 K+ o* X' y1 X; ^0 D
  26. *********************************************************
    ; S4 Y! P; }) h, O! k4 U
  27. */9 s8 k# q1 T5 ~+ }
  28. void HC_SR04_startrange(void)
    + B, G7 T9 K/ a$ b1 Q5 Z6 d  i
  29. {
    . m0 C4 P, V7 T7 T4 q
  30.         HAL_GPIO_WritePin(HC_SR04_Trig_GPIO_Port,HC_SR04_Trig_Pin,GPIO_PIN_SET);5 ?# Q5 Z, @$ Y- A
  31.         //HAL_Delay(5);4 ]) J, P3 S' E+ y  V/ A5 V
  32.         Delay_us(10);
    $ m$ a5 h, R3 g" Y
  33.         HAL_GPIO_WritePin(HC_SR04_Trig_GPIO_Port,HC_SR04_Trig_Pin,GPIO_PIN_RESET);
    4 x: H+ N# v3 J0 Y3 N
  34.         
    7 P4 ~7 e' ]3 N+ H0 q
  35. }
    8 N; p$ I- v; s$ L: Z/ i" k
  36. /*1 ^$ {/ w/ Q8 Y: B  g
  37. *********************************************************+ W& W2 Y! G* Z( r9 ^1 i! C1 o
  38. 函数原型:uint16_t HC_SR04_gettime(void): ~" N  v, k" C8 p6 R& Z( \$ ~$ D
  39. 函数输入:无
    ' x! q# g' @4 R* }( g3 A
  40. 函数输出:无符号整型
    ; C$ q) e8 e" B  r$ s
  41. 函数功能:通过定时器获取当前时间
    : o6 m8 a9 W1 p" M" E1 C* d
  42. *********************************************************
    # h9 E$ U- V7 [' ?- M
  43. */
    8 a" g6 B+ A9 r; J  }5 M% r
  44. uint16_t HC_SR04_gettime(void)
    5 u4 i, c( q$ X2 ^; y2 Q
  45. {
    7 Y  h" R% i7 k6 J3 [
  46.         uint32_t a;
    4 t1 b& K. z& V
  47.         a=TIM2->CNT;. A+ [, G/ ~& q
  48.         return a;, h; D6 h: o, I
  49. }2 a9 T8 V' A6 c6 ?3 l
  50. /*1 @% M1 d+ K4 d+ V5 A' q
  51. *********************************************************+ M' b! c3 |' |' C3 K) S
  52. 函数原型:float HC_SR04_getdistance(void)0 W! n6 h5 w/ |
  53. 函数输入:无' d% t- Q9 I+ H! U8 f6 B% {
  54. 函数输出:浮点型
    : W& [  e  t2 ~$ W% K2 H: n
  55. 函数功能:获取与目标之间的距离' w7 Y  h) |3 A3 P& R( C. E! O3 B9 g
  56. *********************************************************
    8 D, [7 h2 H2 E, L2 R
  57. */! `; H9 e# P, t& R4 i
  58. float HC_SR04_getdistance(void)
    ; ^& R* T5 ]3 p$ N% U5 {+ H& b
  59. {   
    ! g1 c  c/ ]; t. m, S: T
  60.         uint16_t time_node1;
    : {" l& Z% Q! c$ H7 e4 T
  61.          uint16_t time_node2;) z0 x# P/ P2 ?- n; ^8 }' h( g+ ]
  62.           uint16_t measure;/ I# B1 j: m- k0 v* p0 R
  63.         
    2 P7 K& M( ~, |1 w" W! q0 W
  64.   HC_SR04_startrange();
    - H- w( r1 K% C. O) _
  65.         : I2 J  ]* r! r9 b
  66.         TIM2->CNT = 0;
    7 t5 W  \' {2 N, Z
  67.         . u" J0 ?8 N& H
  68.         //有信号返回则通过IO口Echo输出高电平,高电平持续时间即为超声波从发射到返回的时间,测试距离=( 高电平时间*声速(340m/s) )/ 2
    ; f  ?9 K6 {- `& A$ V' R1 I
  69.           while(HAL_GPIO_ReadPin(HC_SR04_Echo_GPIO_Port,HC_SR04_Echo_Pin)==RESET);  w) \1 d1 y1 {6 I# ~! W8 n
  70.         time_node1=HC_SR04_gettime();
    9 V2 @% k8 @' G$ _: o# k
  71.         
    . s: w( @8 d/ M/ _( [2 t" \6 P9 e/ |
  72.         while(HAL_GPIO_ReadPin(HC_SR04_Echo_GPIO_Port,HC_SR04_Echo_Pin)==SET);3 \- z/ _  l* H+ }
  73.         time_node2=HC_SR04_gettime();
    ; T, n% P- g8 n
  74.         ) T; y# L0 T# _# q" C/ a1 ?
  75.         measure=time_node2-time_node1;
    , `3 F: T) r: e6 c: n
  76.         1 o  A, d0 I" z4 T) Y
  77.         distance_result = measure * 17.0/1000;//距离=计数差值(us) / 1000000 * 340(m/s) * 100 / 2 = measure * 17/1000
    0 N$ S- u7 J# o

  78. 1 H6 y: q  J3 g" c4 o6 S; q! q; S
  79.   return distance_result;* q8 b  r2 ]  t1 w6 q) D, F1 w
  80. }
复制代码

& a9 i) n4 E2 z, V3 QHC_SR04.h
' {7 n- p* B7 p) A$ U, B
  1. #ifndef _HC_SR04_H_
    ! }0 b. H8 e4 @2 j- z7 e
  2. #define _HC_SR04_H_7 x. X( L# v  J, W5 O# l7 L
  3. void Delay_us(uint16_t time);" Q: t6 R. G4 v  O: |
  4. void HC_SR04_startrange(void);
    ( }4 I" {; M9 t- T
  5. float HC_SR04_getdistance(void);
    . Q- J( T  E& X- E7 _; f. j: r, T
  6. uint16_t HC_SR04_gettime(void);& K6 ^- o: E1 ]6 v! F
  7. #endif
复制代码
5 q" x9 |) O# v% F/ G+ ~
main.c
& X3 S- i% s/ Y3 U$ j' e  J
  1.   /* USER CODE BEGIN 2 */* t1 c: R, J0 J6 r! I8 z/ g* a3 N
  2.         HAL_TIM_Base_Start_IT(&htim2);
    4 T. t! f7 D# r  K) ?! T
  3.   /* USER CODE END 2 */
复制代码
  1. while (1)
    " X. z7 G4 r2 N" a: e6 U* S  N
  2.   {
    . _/ T# q. }- ]7 O9 W1 V. g
  3.     /* USER CODE END WHILE */
    $ v+ T& X2 n2 W1 B, c) W- F
  4. ! U3 |3 D7 H0 l; {9 M3 i( i* Z
  5.     /* USER CODE BEGIN 3 */5 |% j) V& k: W4 z
  6.                 if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == 1)
    ( B, M! S% H+ D% n
  7.                 {
    2 H  m! p3 l: K9 e% f/ Y) h
  8.                         //HAL_Delay(50);
    ) s# \' \' x: w. t, Z* d; c
  9.                         HC_SR04_distance=HC_SR04_getdistance();$ \) E" i8 S( e9 _8 f
  10.                         HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);//灭灯; }0 u4 N8 Q! \% v& V) n( p. G
  11.                         printf("有人,目前距离为:%.2f cm\r\n",HC_SR04_distance);7 U0 T$ Q( ^& s9 p$ R
  12.                         HAL_Delay(100);& H! I8 x' S8 Q6 F& L! N3 j/ M
  13.                 }$ q, \) D: I4 e  W" l0 b$ O
  14. 4 U  Z+ B  t- P' d
  15.                 else  ! p* x8 y( g* }; k, z9 X
  16.                 {6 v( O8 ~  c7 l) X  b& n
  17.                         HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);//亮灯
      m4 k1 U0 `; U; J+ T2 I/ x
  18.                         printf("没人\r\n");3 j' ^' @* [" t" a4 C  }) v2 H
  19.                         HAL_Delay(1000);) ~7 j2 C" g5 q: r: k) ~2 v
  20.                 }
    5 N5 z2 @) v6 ~& M+ D" C
  21.                 , G! V7 g7 J" m. H5 h, X- N
  22. //                  printf("hellp\r\n");
    * X1 g0 F: w8 ?
  23. //                        HAL_Delay(1000);
    ' F: R/ u, V4 F( G/ s3 Z% T
  24.   }5 Y$ K( W8 {4 G6 Y" v1 @! k% w! F
  25.         - Z4 G' v, V3 O6 M( m
  26.   /* USER CODE END 3 */& P0 K0 a- Z3 p! w; U
  27. }
复制代码
' x  t( J( Z% d* `8 P: v9 g
现象:. J7 ^7 O& H& P( W3 S

6 S- {+ C* @$ y% k; ~感应到人体,板载LED绿灯亮,同时串口打印测距结果。
9 R2 v: {$ e6 m" L9 A* T+ d; H
! z( _0 ^+ {6 N9 [$ ~8 Q: J( G3 n% @ ' c! x* K$ v6 d9 v4 n

+ o' e2 h  ~: P8 X3 L$ q. U3 n- {注意:
& B9 T, T2 \" n% S9 T. s重定义printf后,必须在target里面勾选上MicroLIB,调用一下这个微型库,不然一直卡在里面。
' F% j% b5 F1 j8 _3 K' i& c5 z/ E" L. I
6(B(NQX6N322(SRUM`I)[WF.png
& }' D2 o# F- P$ G& {9 ^4 g
+ i6 P& A9 n  r4 b, t5 `( z. k( Q( `( J. G
6 Y3 D: `1 k% c/ r. N- P7 F
收藏 评论0 发布时间:2022-4-15 10:00

举报

0个回答

所属标签

相似分享

官网相关资源

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