|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
下面是关于stm32驱动超声波模块的一段代码,有需要的朋友可以复制参考,希望对大家能够有所帮助和启发。6 H- ]4 P: y q" Z* k
& ^2 o- N. e; ^3 f: k/ \ s3 [! F* H2 c* T
: n4 U) i# v( J: O# H( @, M* k z8 S2 c$ F
- #define HCSR04_PORT GPIOB
7 y5 U- o h" F' ?' t- p, x
$ w8 Q6 |/ L$ [& z9 A! I! W' u8 _+ y- #define HCSR04_CLK RCC_APB2Periph_GPIOB5 s: E+ n6 j3 l. k0 \ d
' W& b2 n8 Q1 U# n' e8 P* Z- #define HCSR04_TRIG GPIO_Pin_8
5 `; p" A" l% D- W( U% G: E( }& Z - . S- S- U/ @7 q7 N* T6 A
- #define HCSR04_ECHO GPIO_Pin_9
+ D" l3 z( g: W, v. i - ) {1 T4 f# O, ?
- #define TRIG_Send(n) do{. o2 ]6 f/ U. m7 x. w1 S) F
$ y! K/ u& b) Z5 y. l- if(n == 0)6 i J# H7 F2 a/ [; {, t
- 7 M" {+ s& ^5 q8 x6 g- B& b5 c
- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);* `( C, X; n! g7 @* T" T6 K
, b# o; W* W! Y! d# U* x6 z. I- else if(n == 1), f8 t4 |3 |# T* @5 S& C3 n
- " y. Y# b) v, b$ {3 j7 ^0 Q! ]
- GPIO_SetBits(HCSR04_PORT,HCSR04_TRIG);/ { a" s. c) K. D! \
7 W* S# w. y7 I* O( c3 f9 K- }while(0)
) {9 ?$ [6 G* U2 Z7 E. ~$ }
: m; k" }8 k1 R+ T1 ^- #define ECHO_Reci GPIO_ReadInputDataBit(GPIOB,HCSR04_ECHO)2 Z7 u, `0 \; B- ?, w
9 C: m8 R1 `$ w1 J0 }) b( y6 N- void UltrasonicInit(void)2 }$ e5 i; A6 C3 k- M0 C
# n4 l" Z2 b; I# g" f5 ~# @- {0 B& J1 C9 z( X* |! j+ y0 f
- # e: Q5 h0 V4 ]
- GPIO_InitTypeDef GPIO_InitStructure;" E1 ^3 K9 f5 s- }2 M1 |6 q' s
- 3 I0 R( c. ?" B" G0 e3 C2 g
- RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);
) g1 u) d( x! H% _
# d0 L. h% d- k0 h- //IO初始化" F/ t$ ^+ h% v0 t5 u$ H( S: N
- $ [9 D! R3 Y7 L/ k6 n
- GPIO_InitStructure.GPIO_Pin = HCSR04_TRIG; //发送电平引脚. N) x3 O7 C+ E: ^7 q& Y
- ! v' [1 x/ X' e* x
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;( [2 K/ G) M1 @& i. J
/ e f/ X% u+ m4 @- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
% }- J1 C( O) m- Y. n. G
2 U3 s* C6 e3 X- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
' U2 A4 ~+ z0 W7 `- E. C
+ j' X7 e V2 y! p: r# }- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);" u, m4 l# O7 c' Y. `3 J
- 5 F$ W9 K/ C5 v3 r x( u+ b8 u
- GPIO_InitStructure.GPIO_Pin = HCSR04_ECHO; //返回电平引脚/ |1 c. r* n: y
- 8 I; R, Y: N2 |* G4 D2 \
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
( q4 L' A9 T( m E: U4 X: c - 8 c. W# o) m6 h1 x5 h
- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
) Q5 U6 _9 l* D( Y6 `
6 h8 f1 {) }5 j7 P9 R$ q8 O- ~- GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO); k; @( E) I$ ?, E( s, p) E& X
( M- p- z. ~" K0 e( C- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //生成用于定时器设置的结构体
( l2 ?. A% D( |' O; e: k' I - ) d3 a1 _7 b3 ~6 R2 K
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //使能对应RCC时钟
2 V/ _! Q- _, ], I. e
% N D' g3 N$ P8 @- A- //配置定时器基础结构体
# M) b& s& v! m I0 y9 d7 e - 5 M+ c& J. }2 }# z/ _% q% P
- TIM_DeInit(TIM6);
6 ]# w& M( q8 N% [# C; p5 n/ H4 L
+ F+ F. e" i& v8 S! o, d$ N2 W; Y5 D- TIM_TimeBaseStructure.TIM_Period = (1000-1); //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到1000为1ms) ]1 I$ z* g4 C) M0 r
- / u9 C# y8 ^. Y) q i/ z
- TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //设置用来作为TIMx时钟频率除数的预分频值 1M的计数频率 1US计数
, K; D* U) p% G$ S- g" T! O - & v( o1 B# Q# u+ M6 H3 ]8 @
- TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//不分频
# C4 i3 Z5 t Y4 d" O& {
/ E, ?+ s5 F T' t! H% K9 {$ n- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
/ x% _0 H2 E* F7 K: V/ l
6 e( y! S% U. e; a3 n: Y E. Y- TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位% a/ t. o9 V7 m5 X
- , L* H4 P- Z, ?# ?3 e
- TIM_CleaRFlag(TIM6, TIM_FLAG_Update); //清除更新中断,免得一打开中断立即产生中断" \5 u" I6 r) m1 u4 ?' F9 R
3 Q* Y; g: G1 f# C' S2 g% J- TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); //打开定时器更新中断7 `. f2 ?; {3 r+ C7 O5 F
0 {! \. T8 [1 L- NVIC_InitTypeDef NVIC_InitStructure;
' @. N I+ Z' ~2 I+ H - ) f4 O& m. @ i, G M7 |
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
9 ?+ H$ R F( k - " T9 h; q' k2 {( V# w( P% j
- NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; //选择串口1中断
/ R6 ~$ C) _ v9 `* D+ q- ]0 i$ }
: k, h2 v; B# B3 s4 w, \- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式中断优先级设置为1/ _* ?( W# A% c! z
- 0 }; p* P4 l+ _1 o" M
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应式中断优先级设置为15 c5 v, {3 T# {2 A" m
4 H( n& [8 o" T' }! N8 a! y- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断! V! O2 n, r# a: C2 h
- - C8 l3 T. v$ a( D8 M
- NVIC_Init(&NVIC_InitStructure);( H$ T, Q. S# ~7 E9 J5 i# q
! x; [% k0 B4 {8 u" L+ z \- TIM_Cmd(TIM6,DISABLE);
) i0 I$ M; c! }' t7 b - : k- q/ o w- p3 s8 I
- }, A$ a5 e( A9 h" Y# M* a. y
, ] L% [. b) r. u- //定时器6中断服务程序! C- A B5 P! a' [ M" e; R
- ! A5 w# U0 m" k1 e) L( f6 b/ `0 A' g Y
- u32 msHcCount = 0;
: z, f. b4 `0 t - 5 i* s; H5 U$ M% O- x9 N+ k
- void TIM6_IRQHandler(void) //TIM6中断2 @2 a' ~3 h# V
- @! Y; R. F7 B# u2 y9 E
- {3 T- T6 g) C L8 x
H. Z/ A# P: l/ R* q- if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
{8 }2 p, }+ l4 Q
' d7 X4 y$ g8 \8 z5 u/ v3 g; ?- {
5 d/ h4 t; W; d' O1 n) W* ] - 1 Y( l" [& _/ ]# E4 @2 U3 A
- TIM_ClearITPendingBit(TIM6, TIM_IT_Update); //清除TIMx更新中断标志+ Z2 G9 @- t$ A0 p4 u. I
% j8 ]6 `& `* j% a) T- msHcCount++;
. _/ l1 @! v# f' f4 C8 n$ n" W
1 g* c* r$ ^/ p, A- {" z& E- }
- V/ A8 l, M) n - $ H3 I: B- j0 r/ ~# P; |
- }: X: z# P+ D: ~5 W) Z
- ' u( l+ W2 r% \- R2 s& r7 ]
- static void OpenTimerForHc() //打开定时器
* v% ?/ N6 z1 P6 {9 l
" I. B3 |$ I1 [4 l& n0 L- {
( U8 M8 g# Z& p9 p( R) ^0 x
: M* ^5 I- W* j5 [8 W- TIM_SetCounter(TIM6,0); //清除计数
4 a4 W4 i* H. s8 O - 2 c( G( W& R8 l5 S- Y4 }
- msHcCount = 0;
3 k+ d; |) r$ m6 p, n: N! d0 _% p
7 p/ L: P5 M8 h; `8 B- TIM_Cmd(TIM6, ENABLE); //使能TIMx外设# I8 ? F: p& C1 y
* ?& W3 I/ [% `( T; N) n) q- }) u* s" o$ B) r" d* w% m
- 7 ?7 w/ b8 }! M) b2 K
- static void CloseTimerForHc() //关闭定时器
, {* `3 g7 C" g6 T- W - 4 P0 k# y: w+ b2 u
- {
7 T# K6 H# C" \1 W - 3 m4 |; X3 L$ J% D0 ]: ~# i
- TIM_Cmd(TIM6, DISABLE); //使能TIMx外设
1 G3 T( q+ v' v! [& @, b
( n4 @! ?" p3 s3 Q- }* [, I9 X' X% P- g
- % D, ?4 h' t* @+ P4 @6 H' I- B
- //获取定时器时间
- m& k- t1 o) k, n
/ D, c2 n, Y T0 G" R- u32 GetEchoTimer(void)5 E ]6 T7 ?. ~7 A% u4 z
$ Q+ r9 v* `, N" f$ F# i1 O# y- {' p; Q2 K2 v, d
- 6 n ~* t- I+ P h5 y: k/ h, ?6 D
- u32 t = 0;. ^0 x. j4 h5 V! m9 L
( [6 d) m: W5 `- t = msHcCount*1000; //将MS转换成US
$ f* X1 H. b x+ T - + F& }& ^ F0 F
- t += TIM_GetCounter(TIM6); //得到总的US
7 g7 k/ d$ |! K# v5 ] - ( M: N5 [ c1 ]
- TIM6->CNT = 0; //将TIM6计数寄存器的计数值清零
6 P# a/ Q8 {( [$ P3 s5 D% M
- c1 \ z' h+ z# A+ Y5 y- return t;
. ?1 {4 h* C- S D3 a( } - , u+ @9 _6 u6 }/ C# V8 T3 E
- }, O, p7 G$ W4 p" V# {# `- `
6 n" a3 D! N$ Q) u1 r- //一次获取超声波测距数据 两次测距之间需要相隔一段时间,隔断回响信号5 O+ d- {0 W4 ^; A; @1 ^4 K5 k
) }1 I8 t C( \0 r9 ^5 z. k- A- //为了消除余震的影响,取五次数据的平均值进行加权滤波。1 v& j4 K [ m. n2 _$ U
, T) C5 ~' i5 z" C- float Hcsr04GetLength(void ), R1 Q/ ~) v3 m/ ]$ g3 G
, ` L6 {2 G% f; p& P- {
" N% R+ X2 l: s& A o, @
7 T/ K b1 ~ \' x+ w- u32 t = 0;
2 {; t+ u2 Q$ L* k- G1 p; h
5 D! M9 i6 @* M/ U- int i = 0;" F- Z" ?. H6 {
- " X3 I2 P( J- e! H- X a
- float lengthTemp = 0;
8 a8 W* ~. A3 M+ a& Q S" _
) K# Y% y+ Z5 }8 K# X y- float sum = 0;
: C9 Y, D" b6 T - 4 }+ f7 p; Y3 ^% f/ A# F! w O
- while(i!=5)
% u$ l$ n+ Y! N6 T7 E# r6 Y - , S% p- e6 a) e3 o0 Q
- {
- u: n, V z1 J! P1 c% ~* @4 I - 0 w" ]* ]' l# U9 y5 [3 q2 Y
- /*发送一个20ms的脉冲*/
1 p7 r. Z# \2 S: I L
5 D" K. K/ D6 c4 E' `1 v- TRIG_Send(1);. l) G) Z$ v4 U' w
- . R, e3 S9 P4 }% l# n6 C6 y
- osDelay(20);/ g' X5 {) ?, W [6 j% F/ K. X
- / o" G7 k2 T1 u4 M
- TRIG_Send(0);
& z5 i( R3 O3 `- z# m1 l: J
9 \) E4 p) u1 o1 Z3 y& w! m6 \% _- while(ECHO_Reci == 0); //等待接收口高电平输出(超声波发出)
u' M3 t7 o: F - 4 U" T" b% S5 g% j
- OpenTimerForHc(); //打开定时器
1 k9 D" r- e* }# q - 1 Z) @$ Y$ S/ L% J- Q! ]( F
- while(ECHO_Reci == 1); //等待超声波返回
0 \# U4 G" y3 B6 a- R9 `" K
& E7 O/ \3 c$ i/ ]2 m1 h- CloseTimerForHc(); //关闭定时器6 }" `8 G' D* Z2 z; o& Q
- j/ M/ o% a. V* [" s/ t8 x- t = GetEchoTimer(); //获取时间,分辨率为1US
+ V- F- q9 I% w* Y7 U C( B1 ~
( `7 {0 r& z7 S5 P M- lengthTemp = ((float)t*17/1000.0);//cm
1 x: Z/ [; L! w( q - g( E5 X: `! {- C
- sum = lengthTemp + sum ;
. R7 \2 R" {4 L$ a3 p
, t0 M0 {3 D9 r Y; x6 K- i = i + 1;
e+ o: b& J4 Y - / H( C; |- Z: E. U n
- }
* I: @- X: }7 X. I$ l- s7 f
; x% M- k$ O) C/ }# h" U- lengthTemp = sum/5.0;* C( M! l2 l' m1 G) j0 `" ]
6 t( Q, ~0 V3 ^1 t2 q/ W6 f- return lengthTemp;# l3 b6 G# v+ P# l# q
+ B* @$ M0 h8 i* n9 g6 \- }
复制代码 - K: C$ L5 c; L' a7 d
( _$ A1 a' ~) c( W |
|