前言
# [! T# g; X: T4 ?$ IHC-SR04作为简单的外设模块,广泛应用于简单的课设项目中,十分适合入门STM32。
4 e: r, c% `7 t# D8 W3 |. S
2 W. k# y% P+ Q+ s/ g. M( D一、HC-SR04介绍
. E+ R D8 x1 b- n k( {HC-SR04的介绍,这里就不做累述了,大家可以上某宝上找店家要下用户手册,或者到其他博主的博客中看个大概的介绍。" x! s4 K2 y1 n: b& Z+ D2 ]4 I
$ f; T: r4 e9 K- h: D7 W二、使用步骤8 M; l4 |9 D# C3 g) p
1.接口定义
( W+ q. E' h1 R& U d4 Z- VCC -------> 5V
1 p& M/ T) U H) Y: U1 Z( \* D2 z- B - TRIG -------> PA6
( R, m' k* C/ F7 A& V$ s8 ?9 d/ h+ @ - ECHO -------> PA7# d- S" h; v+ s* ^, p" K+ x/ e
- GND -------> GND
复制代码
- y% {. z! `' ?# n/ N) jTRIG和ECHO两个接口也可以使用其他的IO口继续驱动,在这篇文章中,博主用的是PA6和PA7。当然也可以使用其他的IO口,只需要所使用的IO口可以输出输入高低电平即可。& V; k v; ?8 f. C* W6 k( ?
/ v% ^$ {* A3 f
2.阅读时序图0 }! Y0 p+ v% U5 h
9 a) ~. B I, `% ^/ w8 H' ^) C
如图,驱动HC-SR04需要先向TRIG口输入一段超过10us的高电平。此时模块会自动输出脉冲信号来检测是否接收到了信号的返回。若接收到了返回信号,则会将ECHO段拉高并持续一段时间,而持续的时间便是超声波信号发出到接收到返回的超声波信号的时间。& Y/ P% p5 F5 n S; N
) p+ E( [ V$ v! o3.原理# i# G1 i6 [' p8 N
- a. q; r6 D5 I: S0 _1 `& T4 _
; z- H3 m" |3 n" x P3 w; A, X) {, P. \$ N
原理:IO口发送触发信号拉高Trig,延迟超过10us之后,再拉低Trig,作为超声波模块的启动信号,此时模块不断自动发出一段40khz的信号,当收到返回的超声波信号时,ECHO口则输出回响信号 。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离.2 O. _9 O8 I1 V+ y) K. V, Q* T) r# l- v
7 x; N! g: `2 C( ?4.代码
4 [2 C- f, k5 l1 b; j" `/ Mhscr.c下的代码:4 R$ U& h2 i2 j' W) `
( P" ]' j" B% u' I. r% C$ T- #include "hcsr.h"- { l1 I8 v4 ?4 A8 P
7 l. [* M- I) R- void TIM2_Count_Configuration(void)
: P/ r3 Q- H2 [$ d: H1 R6 n, H - {
- W" X# M$ [3 r3 H0 C; D& b7 G! }" x - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;" j. _ C0 K! J P2 U
-
& T9 T% t+ ~2 A1 ~ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);( |) b* j- p! T. h" G- {
-
$ `! `; E1 [) m, ] - TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //999+1 =1000
( R$ _. i; c- _( `+ d - TIM_TimeBaseStructure.TIM_Prescaler = 71; //71+1= 72分频4 p7 v3 N+ a% ^% T' V
- //TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
8 `4 m) G( `" G* |' R. ]: p H - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
( R3 d3 q' J! H) r0 ?4 L# z - TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);" G) |+ m) X, k9 ?6 |* K4 H) ]
5 ]2 v- m( X. b. b% f- TIM_Cmd(TIM2, ENABLE);0 j% S9 G& C$ d; I1 I" X/ N
- //暂时先关闭TIM2时钟,等全部初始化结束后正式使用定时器前再开启
- t7 g6 G: N C. j6 l - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, DISABLE);2 |- u V+ t! G' r. y3 L) E
- }& p. v' k! E0 ?" [
. ~% n' k/ Y; U4 N( C U# n9 M- //PB6(output):TRIG PB7(input):ECHO
* z4 ?/ b) T7 ?3 F - void HCSR04_GPIO_Configuration(void)1 c, P* V8 N3 K# F1 F9 Q
- {* H H. D9 c+ |! |9 u0 K/ S
- GPIO_InitTypeDef GPIO_InitStructure;
" E: j( h3 N. c" _8 D0 B5 {' h
* G% A0 Z. {! h* M- ^: ?6 U- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
2 o6 ]. b" `6 D# Z6 n -
- ?% i+ ~ x& c4 X - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;* E& I7 M n0 x- P g; H3 G! B
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
, R. G0 l$ F# P8 u" V - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/ _# U( |5 i/ X, Z - GPIO_Init(GPIOB, &GPIO_InitStructure);
6 Z( B7 @! `( w0 G, u3 V7 ] -
0 B) L' _# A/ q# W- c1 O& e - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
9 S9 D9 h. c" e, {- { - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
' C% m5 H3 ^* N4 \9 z - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;2 f3 c0 O H) x5 |5 J
- GPIO_Init(GPIOB, &GPIO_InitStructure);
! H9 c$ e2 q# x4 Z1 f - }5 G. C2 Q. j0 C' I
复制代码
8 u5 _7 I' r- k" U u3 c代码分析:该段代码初始化HC-SR04所使用到的IO口和时钟。并没有什么难度。# G# ~( H5 B) y ]4 g7 `5 S
% `7 D1 D+ {' _7 \' v5 W
main. c的代码如下:+ g4 V% p: p+ C- u! U/ E5 w; T2 r
* x3 ^: N! k( ]- H5 f) b/ L
- while(1) : m5 n, O8 m+ F& ]0 j
- {
! l6 f/ ^6 U, R* Y( V
4 |! G9 ?9 j- F- w! L0 i8 Y- TIM_Cmd(TIM2, ENABLE);% V" T9 d& G2 w: E' F/ d
- TRIG_H;
?0 b/ `# }5 g8 H/ j) T - delay_us(15);
4 k$ w8 [. {8 i* U. C - TRIG_L;
& Q/ C9 k7 g: A2 r3 o5 q" c( d - //printf("HERE");
/ Q7 K9 Y% V+ V. u - while(ECHO == 0);- ?* o2 O& F. L# _8 H4 }3 h1 N
- TIM_SetCounter(TIM2, 0);: H* n0 P: Z. G4 P/ z- D$ J
- : @, m7 C0 A: L& L! i. b. L1 Q
- while(ECHO == 1);
8 t% o! l! J9 |& d* d - TIM_Cmd(TIM2, DISABLE);
5 c& ^- q5 ^5 s1 W/ e8 G - time = TIM_GetCounter(TIM2);
: _6 h2 h) A0 o. W5 G7 p7 } - //printf("time = ",time);: V. Z5 ~% C; o7 Q1 p( K$ X( B
- distance = time * 0.017;$ W( V5 t0 M# }# W) s& Y
- printf("Distance = %.2fcm\n", distance);
4 W9 x( U0 X: c4 _( f* ] - }% V1 w& L1 y( d! _: b* Z
复制代码
1 v% _( Y7 h! S4 M代码分析:此段代码的重点在于两个while循环,两个while循环都是为了检查ECHO的输出以及查询其高电平持续的时间,通过持续时间算出测量距离。' }! n$ o5 [ ]0 l* J' [
! ^. [3 k! U+ z0 h: |
2 L& e# A9 V+ v9 `0 T. W
/ g# q ~ R0 N f |