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

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

[复制链接]
STMCU小助手 发布时间:2022-4-15 10:00
前言3 m! m9 r8 a% w9 U6 ~
我在上一篇文章中驱动了HC-SR501红外人体传感模块,但在测试过程中发现,这个模块的热释电探头过于灵敏了,甚至有的时候往上哈气,会因为检测到类似于人体的温度而误判为感应到人体,所以为了减少误判概率,我打算再添加一个测距模块,在红外感应到人体时,再次判断人体与传感器的距离,在满足预设的距离范围时,才确定有人体接近,进行后续操作。' O* z* M5 t, u# b3 X
一、模块简介3 Q9 b! k) M5 P; c3 k7 c* t
HC-SR501红外人体感应模块资料介绍:
/ ~2 h, |3 _# @/ H5 O# H- n: q! q探究人体红外传感器HC-SR501
1 |  E+ P  U" P: n! q) b/ I+ p) w- A8 }
HC-SR04超声波测距模块资料介绍:
5 b) w" C! |4 V* |: a
; X$ o+ B5 @1 ~2 N  f$ _ [}NY0UME6`THJ~NGH(UFEM5.png
' D, e; b, Q' a. n
; m; e5 q/ M0 E$ @ P93W`1KJ@3I1B%9T~XHA%3M.png * t6 V# U9 B( F- r/ ]7 n7 X
4 q9 F3 r+ U+ i$ x4 r3 g+ o* }* y
工作原理:
/ d, i- b: w; F5 E# ]% p, E' k/ ~2 a1 B) e. g$ n
2440fa92274644939b0de5e59ef1852b.png + B9 u; L3 P5 c+ @' m5 c' X

0 ?; Y, N8 l' Y5 U TTPZ0O8GJDMQZXWX}%P2A.png
6 f2 q4 X8 S3 X  n) q& Q5 c" q, j* y. Y" u
简而言之:
' S% l# P2 R0 f1 Y* w9 l给Trig一个10μS以上的高电平,模块开始工作,模块内自动发送八个40khz方波,并自主检测是否有电波返回。此时需要检测Echo处的电平,当为高电平的时候记一个时间;当Echo出为低电平的时候再记一个时间,这两个时间的差就是高电平持续的时间,最后用测距公式进行计算。
( h- Z+ ~- ^6 h) ^6 j
& y$ \8 Y. T7 r! l7 m: T' x二、配置CubeMX
2 R1 _' H3 a( P$ ^/ F% Z. _1、新建工程;
3 @% D" [3 t# Y% `% n+ v2 q! d2、配置时钟源,在RCC里面的HSE配置的是晶振时钟;
, y4 X+ ^( y$ c- Z6 R3、配置程序烧录引脚SYS为SWD模式;
( q4 J6 k* v$ t3 U4、配置GPIO输出口,配置一个LED灯(我的板子是PC13),起到检测到人体时的指示作用;
# n% Y+ v* k1 b# `6 W, u5、配置GPIO输入口,用来读取HC-SR501模块的输出电平,我选的是PA1口;
: ]; e$ b5 U; z7 _6、配置GPIO输入口,用来检测HC-SR04超声波测距模块的回响信号输出,我选择PB5口,命名为HC_SR04_Echo_Pin;+ @; K8 N/ |" \/ h1 ]+ x  N6 C$ h% k
7、配置GPIO输出口,用来触发HC-SR04超声波测距模块,我选择PB4口,命名为HC_SR04_Trig_Pin;( I$ C  C- ^$ W) Q5 j7 Y
8、使能定时器,用来实现微秒延时,和测量HC-SR04模块高电平时间,我选择TIM2,并使能TIM2中断;
9 J, F& k; _. {! _4 p% Y" u: F. |# D  i
Y}$I[3U85M8EJX0`TSX}Q@P.png
! `! s& ]7 l1 o+ w7 {" P- h5 \) N1 T2 ]+ U: @
TIM2挂载在APB1,时钟来源频率为36MHz,故取预分频系数PSC=36-1,计数周期Counter设为60000-1。即此时定时器频率为36M/36=1MHz,每60ms进一次中断,60000μs对应实际测距范围大概为10m,远远超过我的需求。9 b& R' O/ x% ?/ f" I

% Y/ P/ S5 r, ]7 l' A" a4 G- P CP1WI%N(~F}{56Z8OZ{NHN4.png
) e, Y: T7 W0 L# r/ ^8 m. L
# M2 x# G4 d1 D! D, T! a) z9 R 14c2aefe04d5410b89a5300226b73aa6.png
5 X+ i; p& G7 G+ l& G0 ?
( R, g$ `4 v# ~3 O# r+ {9、配置串口收发引脚;
* w- }& q* n6 p" ]# j/ p10、配置时钟树,我还是开到最高的72MHz;2 E7 H* P# |" P
11、进行项目设置,最后生成代码,CubeMX部分就大功告成了0 e% C% |+ s1 b

& Q( S+ L! ~2 D- W0 ]& x B4M6VI[W3NYH~IN2P13@NCA.png
' y" e2 F0 Y" U9 ^% K6 x2 p" f' i8 j+ ]. ?0 F( ^0 x4 x
三、硬件连线部分' b& t. K8 Q7 _4 G- X$ X- r
CH340 ↔ STM32F103C8T6最小系统板:
% M3 t- [( p* Y. A( f9 L2 T. s5 \ TX    ↔        RX
" P/ p" B4 h# y0 [: v RX    ↔        TX$ u% T% c1 [  v" w$ T2 N2 Z

* y: R3 O) o' C' nDAP-LINK ↔ STM32F103C8T6最小系统板6 x" m. L/ h  q) c2 z
  3.3V    ↔         VCC7 ?9 Y1 x! t) \  E
  GND    ↔         GND
  r# F7 R! b3 u# A! k  SWIO   ↔         SWIO" L; i0 @* j# q0 Q7 [/ c; f1 }+ g
 SWCLK  ↔        SWCLK, y5 F( |- ^8 ^7 G

4 @# ]+ p5 D( |6 B; X7 v% ~HC-SR501模块 ↔ STM32F103C8T6最小系统板
" D! d7 {6 S; P    OUT      ↔           PA1
6 I( _5 k, W2 S! G7 d    GND      ↔           GND
% ]3 |3 u' h9 z1 a& {+ t
) M3 y( k: J( o2 b( c' IHC-SR501模块 ↔ DAP-LINK (这里注意模块供电范围为4.5V-20V,用3.3V无法驱动). I/ Z$ ?6 I1 }) @, u9 ?
     VCC     ↔    5V" x6 ^! [0 G0 [- Z. H) G

/ L' A% i- @( p6 {3 L/ {: sHC-SR04模块   ↔  CH3405 t4 X, P$ I0 u% Y
     VCC      ↔    5V- r5 `" }3 t! n% Z
; _+ l/ f: O# }& h
HC-SR04模块   ↔ STM32F103C8T6最小系统板9 H. r" Q$ F5 ^
     Trig       ↔          PB4
, N5 h( x4 b* p# l: E( R# P     Echo      ↔          PB5
8 Z1 M. R; x6 B: ]3 o% P: e     GND      ↔          GND
4 U) I% P0 M& e1 p( g$ A, ^3 j- O* b
四、逻辑代码部分6 w; G4 N& a+ T$ n7 ?
代码框架是基于上一篇HC-SR501红外人体感应模块修改而成的,想要完整代码的话可以和上篇文章一起看。
8 i- Z. t6 h8 w; X) c) H) Y7 X( y8 G3 H) y! W2 u' e
HC_SR04.c. m* Q5 o: O- m, r4 I
  1. #include "main.h"6 B7 j4 U. r/ ^/ G0 ]
  2. #include "HC_SR04.h"' x3 f" M0 G: y: V5 v, Z# D+ b
  3. #include "stm32f1xx_hal.h": z3 l: V# V  P1 ^* O, R* }
  4. #include "stm32f1xx_it.h"9 G2 G! j/ E' _" U: `  _; A8 k) q
  5. 0 E2 \+ S6 y" A$ L, k7 f
  6. static float distance_result;; k9 F- D4 Q0 ?/ v+ z* ~
  7. /*
    . z5 y6 W2 u  d4 F6 Y' N0 t
  8. *********************************************************8 }6 c" h# g/ o  P7 P  l5 ]
  9. 函数原型:void Delay_us(uint16_t time)
    0 H: d. H: J! x7 Y. _( N  x) ^- y
  10. 函数输入:无符号整形
    4 v% M4 K# K- h4 p
  11. 函数输出:无
    / N1 X" V( |- a0 {
  12. 函数功能:利用定时器实现微秒级延时
    : }* G. ~8 |9 p( Z
  13. *********************************************************9 i5 l$ B* H: ^* H: E3 r
  14. */
    / c, u9 \% N8 k
  15. void Delay_us(uint16_t time)
    7 [  C8 F. q0 t5 Y$ N: n1 b2 q; ^. X7 o
  16. {
    & q3 u6 I1 @9 q8 u- T* e
  17.         uint16_t a1=TIM2->CNT;
    - |9 o4 W/ w- |9 y
  18.         while(TIM2->CNT-a1<time);
    9 K7 U" I7 o9 M8 x) j
  19. }2 `0 Z6 s6 B/ Q, O
  20. /*+ A0 I6 w) s, X* }* X
  21. *********************************************************
    2 ]( K5 s2 w2 V4 v' `
  22. 函数原型:void HC_SR04_startrange(void)
    % T: J6 Q6 Y5 t7 n3 I, V
  23. 函数输入:无; e7 R( _0 }6 d9 ~+ j
  24. 函数输出:无! l. F3 ~: Y; c6 r
  25. 函数功能:从trig引脚生成一个不小于10us的高电平触发测距,触发后模块自动产生8个40kHz方波,自动检测是否有信号返回
    4 D* u6 s" ^/ A; e0 x" P0 {
  26. *********************************************************
      h5 }% l* \" d# f) D
  27. */
    6 e/ b& W* g5 {" c2 x7 F
  28. void HC_SR04_startrange(void)1 L- E! J! H( q
  29. {
    ; m; ~# m0 E% u2 p% M) Y1 U6 C
  30.         HAL_GPIO_WritePin(HC_SR04_Trig_GPIO_Port,HC_SR04_Trig_Pin,GPIO_PIN_SET);
    0 T3 [, Z" q1 Z3 f, q* h
  31.         //HAL_Delay(5);
    # ~  N  {1 `: c3 F
  32.         Delay_us(10);
      l+ L# s8 Y8 i. a
  33.         HAL_GPIO_WritePin(HC_SR04_Trig_GPIO_Port,HC_SR04_Trig_Pin,GPIO_PIN_RESET);
    8 y% o8 b9 D/ [8 s6 q- `8 j
  34.         ' N- C/ I3 w1 l+ D' O6 c. E7 [" U! _
  35. }, s$ T* _( @. t  U. k8 F
  36. /*8 X8 [, S9 d0 z, S
  37. *********************************************************
    4 i6 j1 K, K+ C7 z) X. l
  38. 函数原型:uint16_t HC_SR04_gettime(void)
    1 [# p, h9 Y# |  E
  39. 函数输入:无, q' _% Q* u; R7 n" U4 B
  40. 函数输出:无符号整型/ v, t: s$ ^2 [
  41. 函数功能:通过定时器获取当前时间
    . @# r  g1 v- u& `% d) _) r
  42. *********************************************************
    ; W  N5 ^: A5 O  H
  43. */
    0 m2 N, X1 v1 `5 m; f, W' j
  44. uint16_t HC_SR04_gettime(void)6 G5 J0 N6 ]  W2 n7 J* ^4 s
  45. {. K! M% a, Y! E
  46.         uint32_t a;
    . O0 y8 d7 |* q: B( n4 u* T1 S9 h
  47.         a=TIM2->CNT;
    ; g. ]. |# j. L( l+ y
  48.         return a;, F" n, T. J' D6 T& o
  49. }- T9 q% E' u4 j1 \! {! C
  50. /*
    ) ]* `4 B$ _3 b, r2 K
  51. *********************************************************
    & A4 f6 L6 d+ ~4 F- r
  52. 函数原型:float HC_SR04_getdistance(void)
    . n6 M" ~' D, U; [; ]% x% y; E" q" Q
  53. 函数输入:无
    , z1 Y' G) u8 n) @# v
  54. 函数输出:浮点型
    # E% C* P7 J$ P+ h, f
  55. 函数功能:获取与目标之间的距离; b9 v' q& \" a7 ^  X$ k; ~% K
  56. *********************************************************
    ( @- V2 H; V$ I4 B, Y
  57. */
    : c1 S4 I2 g/ p! h9 T* Q% }
  58. float HC_SR04_getdistance(void)+ {" f, [6 R+ \. V( W" M3 [2 s' f
  59. {   & S: S$ M" ~$ r3 P7 Q9 q
  60.         uint16_t time_node1;
    7 j( @4 h5 e4 e) J8 B  `
  61.          uint16_t time_node2;
    4 v- R! q+ Y& v3 R! A
  62.           uint16_t measure;; Y* Q8 n1 S' F# [3 n' Y% h: @! A
  63.         
    ( c$ F* G! Q' X3 C) N( ^
  64.   HC_SR04_startrange();
    3 C4 ~8 ?. w: `1 T8 }$ y, c: I1 J
  65.         & B6 Y' L+ ?: m- w! k( y: A4 B  k
  66.         TIM2->CNT = 0;3 f) b8 V' @* w0 |; R
  67.         . u6 U6 ?3 _: D" `
  68.         //有信号返回则通过IO口Echo输出高电平,高电平持续时间即为超声波从发射到返回的时间,测试距离=( 高电平时间*声速(340m/s) )/ 2 / D! f; T' O2 q: K, V/ M
  69.           while(HAL_GPIO_ReadPin(HC_SR04_Echo_GPIO_Port,HC_SR04_Echo_Pin)==RESET);6 S5 @- O9 _" r+ T) j, l
  70.         time_node1=HC_SR04_gettime();
    5 Q# I( o* \6 [! }* V  P
  71.         8 M) A& n' ^" V' Z" e  K: z
  72.         while(HAL_GPIO_ReadPin(HC_SR04_Echo_GPIO_Port,HC_SR04_Echo_Pin)==SET);9 D9 p# f0 W# _2 Y) g& I5 K- v
  73.         time_node2=HC_SR04_gettime();
    ( z6 t1 d4 e) p
  74.         
    5 l! b: p7 a5 J3 g# @
  75.         measure=time_node2-time_node1;
    + i% k  p8 y) u0 E- x
  76.         0 i" \# P% {/ n+ _/ y; ]
  77.         distance_result = measure * 17.0/1000;//距离=计数差值(us) / 1000000 * 340(m/s) * 100 / 2 = measure * 17/1000
    & I; m8 B. `7 q6 P
  78. & L( @% r4 H* |) D
  79.   return distance_result;3 Z- x" \+ m4 Y5 Q/ }; q: e
  80. }
复制代码
! p8 x6 t: {) ]
HC_SR04.h
( S8 Z5 Z3 `' y! [) ~
  1. #ifndef _HC_SR04_H_
    5 ^# ]9 l+ p* m8 R4 A8 |
  2. #define _HC_SR04_H_7 ]/ @$ b" h# y4 E
  3. void Delay_us(uint16_t time);
    % [2 _3 A3 F; _
  4. void HC_SR04_startrange(void);
    0 Y: R  m0 N' z; A9 g7 F
  5. float HC_SR04_getdistance(void);( G8 h5 \, T- O, V, C# f
  6. uint16_t HC_SR04_gettime(void);( v* m8 u# F8 P8 e
  7. #endif
复制代码
# P: X+ v+ g2 H4 F3 F
main.c/ J* F3 [* i/ X1 J
  1.   /* USER CODE BEGIN 2 */6 ^# |0 D( f0 M- ?- C
  2.         HAL_TIM_Base_Start_IT(&htim2);8 k+ I- F; M4 V& V. m3 [' `
  3.   /* USER CODE END 2 */
复制代码
  1. while (1)
    & ?/ Y0 V' b2 B+ c* i. o
  2.   {3 \3 v) g' W4 Q' ?' C" s$ p
  3.     /* USER CODE END WHILE */5 z! a- R, b3 a( H, C

  4. ' M9 P0 n4 n# X' H+ `9 J
  5.     /* USER CODE BEGIN 3 */. _" K+ |$ q/ t) C4 @& @/ u5 R8 r- w
  6.                 if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == 1)
    " g. E5 J$ Z  V! c7 Z: p; i
  7.                 {
    : j6 W3 S/ V1 i- F
  8.                         //HAL_Delay(50);
    / y; j2 K0 I' w2 L+ x
  9.                         HC_SR04_distance=HC_SR04_getdistance();! t$ Q8 ?- M: S
  10.                         HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);//灭灯  x3 O9 X/ ^5 t* S
  11.                         printf("有人,目前距离为:%.2f cm\r\n",HC_SR04_distance);
    4 t" X- H. q6 l# M7 h$ m9 J
  12.                         HAL_Delay(100);
    5 I  D. Y! d) O( S" e* s+ g
  13.                 }/ W5 Z: m% j: X6 V7 `6 f) ?

  14. 6 k: W) Z1 w& J0 z" w+ \) L( G9 t
  15.                 else  
    1 z) W- z' c. B9 i0 a
  16.                 {
    & e7 f8 G9 p6 h
  17.                         HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);//亮灯* X% S2 {% ]  Z8 \+ G0 Q) k' w
  18.                         printf("没人\r\n");4 X" e: _% H! X( a  _
  19.                         HAL_Delay(1000);
    ) Z) F8 G3 q0 o
  20.                 }! A  j! X/ [6 D6 k/ D$ `
  21.                 ; l8 Y. s; A! e7 T- h
  22. //                  printf("hellp\r\n");
    : k! O" z( k- _, H/ f. F( Q8 }
  23. //                        HAL_Delay(1000);" T# T) g6 e! z( }' K
  24.   }( p9 C( h9 E( m$ ~* ~% N6 O! |
  25.         " ]$ L! c1 w  G0 W+ I) E
  26.   /* USER CODE END 3 */( l( L+ K1 Q+ I. D. ?
  27. }
复制代码

% Y" J- H+ K; {1 {$ {现象:
0 T; s- {; j( C# S% R( O
8 |0 ?1 n* n/ x1 w$ }% }感应到人体,板载LED绿灯亮,同时串口打印测距结果。
. k! P% a5 p  ~; Z) t' ~  J
' ^2 K: |9 N$ t$ L# N$ } % U  L5 t* A$ L- Y" {( A

2 u1 |) {. J8 S- n: n# U. C5 [注意:9 ~8 [, U0 D9 i
重定义printf后,必须在target里面勾选上MicroLIB,调用一下这个微型库,不然一直卡在里面。% e, y! m5 d( |- k( R& ~

5 e, [9 O2 }- ]! F" s/ F+ z 6(B(NQX6N322(SRUM`I)[WF.png
' n9 V7 ~: t) W$ v
' f8 n, g: J0 M$ [! p
/ q4 S4 _/ e  L% K6 @3 B, X2 v9 u* w
收藏 评论0 发布时间:2022-4-15 10:00

举报

0个回答

所属标签

相似分享

官网相关资源

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