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

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

[复制链接]
STMCU小助手 发布时间:2022-4-15 10:00
前言7 D9 D2 e. W6 W* K) a" ?: a
我在上一篇文章中驱动了HC-SR501红外人体传感模块,但在测试过程中发现,这个模块的热释电探头过于灵敏了,甚至有的时候往上哈气,会因为检测到类似于人体的温度而误判为感应到人体,所以为了减少误判概率,我打算再添加一个测距模块,在红外感应到人体时,再次判断人体与传感器的距离,在满足预设的距离范围时,才确定有人体接近,进行后续操作。+ z6 w8 `. v7 N0 x  C
一、模块简介+ w' z3 E$ k- H# d/ x
HC-SR501红外人体感应模块资料介绍:7 E9 Q* s/ R; F0 u3 Z; K- i: P
探究人体红外传感器HC-SR5013 Z* ?% a% w- y' V
9 s' c1 `- N. Z, D
HC-SR04超声波测距模块资料介绍:
. k' [  P+ o; T. F! O: V9 l
2 ^# v3 t' M: q( @# ~ [}NY0UME6`THJ~NGH(UFEM5.png * O! Z/ e1 L& {% O- H

. a. y0 Y4 p3 @$ a" ~! @ P93W`1KJ@3I1B%9T~XHA%3M.png 8 u+ d( ~/ Q- O! Q* L/ X( c

1 C( c7 i. b! T, H% T工作原理:4 S. X3 l& s/ |; r! j) c3 o

3 ]6 Q4 a& q+ I/ Y 2440fa92274644939b0de5e59ef1852b.png
( A+ _5 r9 j7 E9 @9 Z6 V: r: R6 R+ M, l) ?' H4 q0 n4 q
TTPZ0O8GJDMQZXWX}%P2A.png
8 w' U* h" d) x3 b6 f4 }3 {3 h" F6 A: V, L
简而言之:  u. {+ c" h% ]
给Trig一个10μS以上的高电平,模块开始工作,模块内自动发送八个40khz方波,并自主检测是否有电波返回。此时需要检测Echo处的电平,当为高电平的时候记一个时间;当Echo出为低电平的时候再记一个时间,这两个时间的差就是高电平持续的时间,最后用测距公式进行计算。
, x% B. E1 f1 r0 T( O, ^$ q
: k( r/ a( w# }5 o7 U二、配置CubeMX
0 y6 P8 M0 M4 Y1 t- i2 x1、新建工程;0 ?, C/ m- s4 P+ t! s, X; V
2、配置时钟源,在RCC里面的HSE配置的是晶振时钟;. Y. P5 K6 Z" Q5 O- L. a
3、配置程序烧录引脚SYS为SWD模式;
5 B. P9 n; P3 G1 Z  q: d4、配置GPIO输出口,配置一个LED灯(我的板子是PC13),起到检测到人体时的指示作用;9 n0 m! w# q  `: m5 _* m; r
5、配置GPIO输入口,用来读取HC-SR501模块的输出电平,我选的是PA1口;
, H# R  H6 v4 r$ f8 D6、配置GPIO输入口,用来检测HC-SR04超声波测距模块的回响信号输出,我选择PB5口,命名为HC_SR04_Echo_Pin;
0 }5 a( Y# q/ L4 e( S: C2 S* M7、配置GPIO输出口,用来触发HC-SR04超声波测距模块,我选择PB4口,命名为HC_SR04_Trig_Pin;
* j; X- t% |! t: T- r8、使能定时器,用来实现微秒延时,和测量HC-SR04模块高电平时间,我选择TIM2,并使能TIM2中断;# J* g- S1 b8 j

+ F/ ^5 K. K/ p* q0 z, r8 J0 w5 M Y}$I[3U85M8EJX0`TSX}Q@P.png
0 g+ W  j1 s7 `: v/ i! ?& a
; }) ^" \2 ]+ STIM2挂载在APB1,时钟来源频率为36MHz,故取预分频系数PSC=36-1,计数周期Counter设为60000-1。即此时定时器频率为36M/36=1MHz,每60ms进一次中断,60000μs对应实际测距范围大概为10m,远远超过我的需求。
1 T0 J% ~2 ~6 M" R% R$ ~0 G' K0 E1 e& M6 q" u# M6 P
CP1WI%N(~F}{56Z8OZ{NHN4.png
! l/ ~( ?1 i) J7 L7 @2 J0 T" w4 ], E, ]' j; G, ~6 `% w
14c2aefe04d5410b89a5300226b73aa6.png + M" J, @6 P; I

7 q) Z5 U/ s; q* _9、配置串口收发引脚;
1 X  ]$ C' M; f7 K* n; A+ j3 v10、配置时钟树,我还是开到最高的72MHz;8 w7 q' k  _% z6 g
11、进行项目设置,最后生成代码,CubeMX部分就大功告成了- \2 q; I' t; \% k" B
7 O- L- `6 L: [1 ]) J: E+ P0 |
B4M6VI[W3NYH~IN2P13@NCA.png ( a. Y. g3 R; v9 z8 Z
8 j& p% R. w9 d
三、硬件连线部分
: ~4 V% ]  w( h* e5 U! A$ BCH340 ↔ STM32F103C8T6最小系统板:1 U, N- E* @7 _: G+ ]0 q
 TX    ↔        RX0 M( {0 m: ^: m' X5 h/ n4 z
 RX    ↔        TX
6 L9 S/ f, x, o$ Z' s+ b3 [* O" N$ L. |. D: B4 E" [
DAP-LINK ↔ STM32F103C8T6最小系统板, ]+ P* V; }) e6 o' ]! M3 p- M/ r
  3.3V    ↔         VCC' L, S2 _8 J8 a  A+ w; v6 F
  GND    ↔         GND6 ?/ p% s8 k9 {/ ^
  SWIO   ↔         SWIO* j7 c$ E5 A8 b! @6 [  T2 J2 y7 U
 SWCLK  ↔        SWCLK0 F1 d3 ~3 S2 W

' l. @+ _; E4 A7 H7 A4 ?$ wHC-SR501模块 ↔ STM32F103C8T6最小系统板' r: n+ f" W) C/ \
    OUT      ↔           PA1
. j. v7 K8 |9 o, C! ~    GND      ↔           GND3 I. z0 n1 O- j
& p) Y) h% f& v: c
HC-SR501模块 ↔ DAP-LINK (这里注意模块供电范围为4.5V-20V,用3.3V无法驱动): O& u( r. Y9 ]/ L$ Z( j
     VCC     ↔    5V; m! g6 L2 c( J& E! K. L

: G4 q% z' P. r; p1 ~HC-SR04模块   ↔  CH340
1 e/ f( ^% J* c& V" }1 A: \4 e6 \     VCC      ↔    5V
2 a6 \( N# b; l/ S: F' u! b8 r5 P
HC-SR04模块   ↔ STM32F103C8T6最小系统板
  J! Y/ O0 A$ ]1 U     Trig       ↔          PB4
0 Z& f9 b6 v3 a     Echo      ↔          PB5# m8 |: k1 f9 j: a) e7 _
     GND      ↔          GND
0 h; K' p) U; i0 e# t* |9 H! z# i2 f9 E& P
四、逻辑代码部分
$ J  ?4 ^/ X9 Q% T5 `代码框架是基于上一篇HC-SR501红外人体感应模块修改而成的,想要完整代码的话可以和上篇文章一起看。
. q* ^+ w# a9 E& o8 o$ }( f
6 D, b; l$ t" H8 iHC_SR04.c2 m0 j+ t; L' i! p1 R
  1. #include "main.h"  u' M8 D% _% @+ M! o+ W
  2. #include "HC_SR04.h"
    8 u2 ]; M! @, s- t4 T% v. O3 c
  3. #include "stm32f1xx_hal.h"( D/ O. c& p" A. b$ l
  4. #include "stm32f1xx_it.h"
    ' _4 r+ W  ?# k9 B. K6 `  ~
  5. 1 D* h# l  A& y9 H9 U; m3 X+ v
  6. static float distance_result;
    8 o/ F4 [/ a/ B9 [& P7 h8 k
  7. /*) C- x. G6 ~$ H  Q
  8. ********************************************************** a7 C: m' |1 ~3 P  |
  9. 函数原型:void Delay_us(uint16_t time)
    4 E$ U! i; W& `/ p) z& U
  10. 函数输入:无符号整形9 D2 W: M" b$ J: ^5 w( w5 ~- v5 F! |
  11. 函数输出:无
    # d1 t; b6 p- n2 S2 u" h* K
  12. 函数功能:利用定时器实现微秒级延时
    ( z: U4 C9 d# K1 ?3 [
  13. *********************************************************
    + V. Q# D% ?0 W( @/ E2 i; U
  14. */
    0 W) A# k$ g8 N$ {
  15. void Delay_us(uint16_t time)+ h* r/ V3 E' C; n" z
  16. {8 }2 n2 F8 n1 c, T: Y, D
  17.         uint16_t a1=TIM2->CNT;
    . Z4 T# J) K& G: C+ A5 m( r
  18.         while(TIM2->CNT-a1<time);0 r3 x" [4 n: y# S
  19. }& ?3 ?+ Z5 l4 K' j9 a) C$ n3 f
  20. /*
    8 |* V$ y  z% q* k+ x
  21. *********************************************************3 C. W  s1 ~" s9 `! F0 e. G, t
  22. 函数原型:void HC_SR04_startrange(void)2 C4 [4 z- ]% l/ P( v0 b
  23. 函数输入:无
    1 X# ^% }6 P& D9 s
  24. 函数输出:无1 z; r, C% T( K* i0 L
  25. 函数功能:从trig引脚生成一个不小于10us的高电平触发测距,触发后模块自动产生8个40kHz方波,自动检测是否有信号返回
    - Y* o$ R) C1 X, J* c! t7 c! N' ?
  26. *********************************************************
    ) T0 f2 U: X# v4 ?! b1 r# Q
  27. */
    8 D9 O: [  l9 X$ u" K3 Q+ s
  28. void HC_SR04_startrange(void)) ^1 {- c% B2 I6 ^) |
  29. {
    % t6 w5 H7 ^- i& ~) ^% A, b
  30.         HAL_GPIO_WritePin(HC_SR04_Trig_GPIO_Port,HC_SR04_Trig_Pin,GPIO_PIN_SET);
    6 s! V& Q$ M! q
  31.         //HAL_Delay(5);4 m+ h' Z) }: i- x$ F# q
  32.         Delay_us(10);: X2 s0 e/ v- W* E( c
  33.         HAL_GPIO_WritePin(HC_SR04_Trig_GPIO_Port,HC_SR04_Trig_Pin,GPIO_PIN_RESET);
    , N+ ^; U3 D$ e! b
  34.         
    : u+ B: C9 I4 C7 d
  35. }1 W! a$ z2 Z5 p0 r# ^8 u
  36. /*3 N) L) E1 }6 M1 p1 x7 o7 }) t
  37. *********************************************************, J( x2 W1 o4 T' T
  38. 函数原型:uint16_t HC_SR04_gettime(void)" K: {+ {, T! e- U  ~
  39. 函数输入:无2 ]  |! a4 b+ b, i# X
  40. 函数输出:无符号整型
    1 b+ W5 l3 X" D( \% ?# l9 ^
  41. 函数功能:通过定时器获取当前时间
    1 w: \' Q. D; G1 Q% U# P3 Q( Z$ H; f
  42. *********************************************************# ?; W1 b) G' v, f8 _% G: j/ `, E
  43. */+ r* s- a( G0 \$ i1 Q. v, p
  44. uint16_t HC_SR04_gettime(void)( r0 B* q+ l4 M7 p2 r2 t. v0 x2 r
  45. {
    7 Y4 o$ j- p% e8 H3 w! `0 s7 v
  46.         uint32_t a;/ G1 i1 ]( Z# i5 K) T5 l
  47.         a=TIM2->CNT;
    3 {8 J5 z8 A' t+ @: G/ J. @
  48.         return a;
    ( C4 s' z( e+ |4 I
  49. }1 Q! Z9 Y, c; L8 D
  50. /*) M8 H& H8 Q7 ?, v/ Q* e
  51. *********************************************************
    2 A9 X  V# |# t
  52. 函数原型:float HC_SR04_getdistance(void)
    : Z$ }# ]2 E+ k
  53. 函数输入:无, _! u' d/ z3 j, t( Z' d" m9 a: c
  54. 函数输出:浮点型
    2 s/ f+ Z: i' i9 i
  55. 函数功能:获取与目标之间的距离1 l0 k, K9 C5 h4 J$ {7 U- t
  56. *********************************************************. K- q; w! p( g
  57. */
    # h+ S; `: y% C0 @9 f
  58. float HC_SR04_getdistance(void)+ \& J& y, a. U/ k$ O6 T
  59. {   6 b9 O; q& T1 l
  60.         uint16_t time_node1;& N- V: ^/ F. Z$ n" M
  61.          uint16_t time_node2;; b/ `1 v" c/ `1 _  |# Z, J
  62.           uint16_t measure;+ q/ e6 S- Q$ @, v$ h8 I6 A: r
  63.         + G1 l  H. _: s& Q: }
  64.   HC_SR04_startrange();7 w* n/ g5 O4 w1 ~; c; {, W1 v
  65.           ~8 [/ r7 a6 D# n
  66.         TIM2->CNT = 0;
    6 F) n" T9 E3 f# i8 J
  67.         3 z& i/ d' S& h* ], A
  68.         //有信号返回则通过IO口Echo输出高电平,高电平持续时间即为超声波从发射到返回的时间,测试距离=( 高电平时间*声速(340m/s) )/ 2
    5 W/ f) g' t( A9 _, R! c1 k8 |* V
  69.           while(HAL_GPIO_ReadPin(HC_SR04_Echo_GPIO_Port,HC_SR04_Echo_Pin)==RESET);
      I( V  Q2 ]6 E) W
  70.         time_node1=HC_SR04_gettime();& i% E) a0 e/ A; r% p
  71.         9 y1 v7 t, w: H( K8 c
  72.         while(HAL_GPIO_ReadPin(HC_SR04_Echo_GPIO_Port,HC_SR04_Echo_Pin)==SET);# d1 b# a3 n9 ^9 u. I7 _$ o
  73.         time_node2=HC_SR04_gettime();
    5 R7 e: T) m+ A
  74.         9 }) @5 M8 z+ N% s
  75.         measure=time_node2-time_node1;
    / X6 n8 w) }- N/ b1 V
  76.         
    ; @8 R7 N3 S* e7 Y, \
  77.         distance_result = measure * 17.0/1000;//距离=计数差值(us) / 1000000 * 340(m/s) * 100 / 2 = measure * 17/1000
    2 ?1 E, [' I% J& c9 G* x

  78. 6 c: N& g; L  |9 C. K3 W: ^/ G
  79.   return distance_result;
    6 Z' Q4 \4 Z  I" b% G2 r& @0 w
  80. }
复制代码
+ K" y0 e/ B/ w/ C
HC_SR04.h
4 _; \! C. k1 Y1 r# D
  1. #ifndef _HC_SR04_H_
    % T' S( F# Y( v5 c& I$ C" ~% u
  2. #define _HC_SR04_H_$ z! y3 ?# ?2 n& ?- N
  3. void Delay_us(uint16_t time);  K* ?0 }# E+ D
  4. void HC_SR04_startrange(void);
    & x3 g2 u* ]; ~  S
  5. float HC_SR04_getdistance(void);0 N# U) e8 O3 G
  6. uint16_t HC_SR04_gettime(void);
    & K* r; `( S& t- }9 a  j/ c
  7. #endif
复制代码

( K& m: f; b+ T! T" ~- _main.c
2 d, K8 o7 n' T3 i" e
  1.   /* USER CODE BEGIN 2 */
    : T6 r6 S8 y+ o& a' G
  2.         HAL_TIM_Base_Start_IT(&htim2);
    2 m& p8 Y; w) m$ X
  3.   /* USER CODE END 2 */
复制代码
  1. while (1)! c, V6 [2 b- L) ?! C8 O6 x
  2.   {
    ( Q9 N* D- N" h, X/ o/ p
  3.     /* USER CODE END WHILE */: J5 F; K; q) ^4 L2 n
  4. 3 C' e: y& Z& u
  5.     /* USER CODE BEGIN 3 */
    3 s5 z. w9 L9 c  ?3 M
  6.                 if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == 1)
      {6 r! l$ ^. W" W0 z- i! x
  7.                 {
    1 J% q6 j3 ~  h; Z
  8.                         //HAL_Delay(50);
    + M& s4 n( z6 ]+ j5 P; B0 k
  9.                         HC_SR04_distance=HC_SR04_getdistance();
    7 P4 y+ u2 e8 E( n. A0 I8 S
  10.                         HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);//灭灯! R9 q( X/ e0 S! u, E9 ?
  11.                         printf("有人,目前距离为:%.2f cm\r\n",HC_SR04_distance);
    4 V5 z! Z: {5 r9 Z! {1 L
  12.                         HAL_Delay(100);: S- v$ y+ U. a, J5 Y. b
  13.                 }
    6 b8 E5 t" v, j# D" @
  14. 1 K; L2 g$ Q: J" i0 ?* N/ e
  15.                 else  
    ! R4 e! K( ]* Z6 B2 Z: u. a
  16.                 {
    $ ^" l8 r/ S$ d4 ^  G4 t4 k! E
  17.                         HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);//亮灯* ?$ S  p& J# t/ g& ]
  18.                         printf("没人\r\n");- ~- H# Z, t4 S1 u
  19.                         HAL_Delay(1000);% y$ Y) C0 |" x7 Y; ]/ z( E2 \: q
  20.                 }( o4 Z7 f; q) f" J. x, }9 r! C0 n2 q
  21.                
    5 d0 m1 c* r+ [0 Q5 @; M; o
  22. //                  printf("hellp\r\n");) [% B+ ?& s7 W6 V# c/ }1 ~+ p
  23. //                        HAL_Delay(1000);; R; x: S7 y# @& z0 `9 x  s
  24.   }; T8 D" t$ t( J- @- e
  25.         
    3 l. U4 r) C. D
  26.   /* USER CODE END 3 */
    4 B5 y# o4 L* Z4 c9 `, K) L
  27. }
复制代码
7 g" B  b4 ^9 a: a4 J5 o
现象:6 x$ M+ y' h, o- D: }
2 h8 Q# ]$ o1 x* _3 ?* a) r
感应到人体,板载LED绿灯亮,同时串口打印测距结果。
! @& X+ ^) v5 J( G5 E) L! c1 {6 k. @5 y& w% r

  ?3 X, A* ^# `2 h$ k* Q, B5 B1 X& K* u2 V% i$ U" }
注意:
- j$ [8 L# ?9 R0 U% x0 \重定义printf后,必须在target里面勾选上MicroLIB,调用一下这个微型库,不然一直卡在里面。
# E& Z4 Z2 O( {$ |3 a6 h) @. I8 N  p1 p' m3 r
6(B(NQX6N322(SRUM`I)[WF.png 9 q) }8 S' e( |) @* h. s' g

) W8 z/ W: `( X
$ b7 v- G* D( X# X% O6 k
0 s) N- J& L9 f4 w5 u, ]2 I
赞 收藏 评论0 发布时间:2022-4-15 10:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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