|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
下面是关于stm32驱动超声波模块的一段代码,有需要的朋友可以复制参考,希望对大家能够有所帮助和启发。
! w( C' o1 x7 K5 t$ [! O" h4 u, m/ G: R& K g5 A
% ~4 @0 u7 U+ c: f4 g& h
+ @& U6 j- `9 `. v
6 c5 F( M$ u4 j! @* ^1 Z; F$ |* l
- #define HCSR04_PORT GPIOB2 Z3 Z* z8 K5 p4 G% g
, E% f7 \$ |% j2 O2 p- #define HCSR04_CLK RCC_APB2Periph_GPIOB8 y; y5 ?7 q {. w
4 \) O/ y* ^/ ^) @" Y- #define HCSR04_TRIG GPIO_Pin_8$ l2 c& h% }8 K8 }( O
6 [6 T; |5 k6 m& W" W- #define HCSR04_ECHO GPIO_Pin_9
" i! ~6 H$ q* {; e* r - , l) q' u) f E- @! Q
- #define TRIG_Send(n) do{
0 j6 M, O/ a: u8 a6 g, U
* N I* u1 A5 b- if(n == 0)
9 Q$ ]5 T( [1 C) W! D
/ y5 n/ x9 V) P, l3 J/ A* D# M. G* H- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
8 p$ p$ }) a- {0 F7 F3 M
# f0 K V/ |+ i8 y- else if(n == 1)
" {% f: w! Q' e, A- o' K - 3 E* \/ \, T) U4 A% n
- GPIO_SetBits(HCSR04_PORT,HCSR04_TRIG);0 c- M/ u8 k k3 v9 Y
- 8 A' K* S, D f; C: D4 p- E9 L/ `8 Y" ~
- }while(0)0 @! B0 [. z& `4 C- o
2 b$ p a% }7 b/ ?- #define ECHO_Reci GPIO_ReadInputDataBit(GPIOB,HCSR04_ECHO)8 L( w/ W1 E$ Z2 D1 L7 y+ r5 ]
- 4 X5 T1 x. K* V* h+ L( l& F, `
- void UltrasonicInit(void)
' @, h+ ?( k8 U$ D$ T& y - 1 C. L. I- w# y S
- {
5 X. \ \; K1 b - - F! z+ W" a; s$ O8 z
- GPIO_InitTypeDef GPIO_InitStructure;. Q+ o( F' W4 X6 E% ?$ D" k
F. |- V# o! c v- RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);
1 }1 V6 T' b) i# N3 Q
- h2 \/ E6 D u' V2 o6 L& U- //IO初始化4 Y: o- D0 t$ b8 E# Q* U# x3 p2 E
% m+ C& i/ q9 x7 j3 z, |6 q% a# N- GPIO_InitStructure.GPIO_Pin = HCSR04_TRIG; //发送电平引脚
9 ?" ]* Y' }$ S+ u8 i
$ _+ H6 r% I, f8 k- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;/ K ?6 D" L H% F0 W
' Y2 @/ h# ?3 d" x) w4 E6 O0 d- f- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出1 A6 K5 y1 n( o7 P5 u$ h8 [9 a9 O
) P/ u4 q9 N% {2 e4 V+ V- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
: ?2 @/ ]+ s8 L - # J* V. s2 _# u0 E* I$ G, u/ k
- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
( X8 A+ A# `) y$ o/ [5 d
$ A$ T1 e" t+ h- GPIO_InitStructure.GPIO_Pin = HCSR04_ECHO; //返回电平引脚
, n( l: O$ Y ? - 2 x6 K' t* ?8 [7 d l @ d3 u
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
C; I+ r0 |: r6 i7 v- k' b9 S - & _# Q& _/ E& l# X
- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
8 _0 j6 i0 F. m) n$ V- R9 B
$ n4 ~' T% x/ c% `, _9 ?- GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);
: T( p: ^' M- i9 ]2 t
/ j6 p9 c4 M& f7 N1 d! h) u4 I- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //生成用于定时器设置的结构体
3 J8 r( A, r6 o/ N4 ^+ g& U- V- ~
Y5 ?" E$ V( C# d. _- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //使能对应RCC时钟( ~: N9 |1 u# X9 G2 D4 {
- . m% _/ i4 a* P2 y6 j- _
- //配置定时器基础结构体2 g4 S n2 a1 u* n& o3 ?
8 B4 q( B& ]' Q; m# ?0 X- TIM_DeInit(TIM6);% m7 F9 K! [' l6 p
- 6 f; a0 {2 \% r& I
- TIM_TimeBaseStructure.TIM_Period = (1000-1); //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到1000为1ms# a4 J# z9 F' N& D' G
+ v+ |# m8 N( T. F+ u( ^8 ~- TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //设置用来作为TIMx时钟频率除数的预分频值 1M的计数频率 1US计数* m" w: ]* |! c5 o
- 6 d% L9 d. H6 t. s: B0 c
- TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//不分频
8 E/ T+ L- \( ?8 d6 F
2 x. z" y9 }1 V. p5 p5 N& n8 _- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
+ P% ?+ F3 r0 v9 e. E6 Y/ a; V
; A, U; `, a) X# o# { F- TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
1 A9 h% r( }' a2 Y' S& i6 N7 j - ; T. J- m0 b% u" J) ~
- TIM_CleaRFlag(TIM6, TIM_FLAG_Update); //清除更新中断,免得一打开中断立即产生中断/ V) b/ P% i* w0 ?( \0 M) E% \1 H
- * R0 J: [) v: w+ k" w8 F+ h& u; E
- TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); //打开定时器更新中断; p. b. Q0 W9 B# T& Q6 @
- $ \/ f" @2 L& Y4 S* k
- NVIC_InitTypeDef NVIC_InitStructure;+ V1 n/ l: S- R. q. a; _
3 D" g" `" C q8 Q/ @" L- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
2 S- \$ W% j: J
9 v0 L! |8 s: a- NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; //选择串口1中断
9 d- R8 P4 E2 D' u/ K8 \
4 a3 b2 |* l, Z9 T6 L4 ^9 d- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式中断优先级设置为1
8 s N# L* e& l
; N- k E0 k$ [" [% ?- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应式中断优先级设置为1
5 y; Y% C$ |& I* Z$ Y
! w/ G- Y- f+ E4 u% L- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断
" k D/ d' ~7 M/ I7 m& b6 ^/ o
3 \" @& M0 r, J! N- NVIC_Init(&NVIC_InitStructure);, d2 G2 R1 e0 m2 x9 [6 F
% f! U6 X* R1 o; P2 G- TIM_Cmd(TIM6,DISABLE);+ W+ _: U' N- b" T1 Z
1 j' [ V2 Y# N2 C5 N- }2 ^; {% R) K. G5 s/ \
- ) s! B: c$ Y& y/ E
- //定时器6中断服务程序
6 o) A: m; h2 ~/ F4 } - 9 T0 J$ h; l, a2 r' R( ]
- u32 msHcCount = 0;
+ g2 n( @$ E3 G: k - ( g( J) L- m; v, R
- void TIM6_IRQHandler(void) //TIM6中断1 S* ~! c# X6 L6 u( {4 L
- # D/ m( K& s5 N. {( \
- {" n+ m" W0 y# ?4 ~$ o. k' O
& W& C; ?& E' L3 f* A. _0 \- if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否! `" [+ h. m' g4 }) m
; p" j3 w) c: \) b2 _- {2 [+ m# J4 G3 q2 M: |* y9 O5 q* n8 x' [
8 a/ \; E. J2 }! N- TIM_ClearITPendingBit(TIM6, TIM_IT_Update); //清除TIMx更新中断标志
6 j: s7 A3 M( a7 y2 ]( n% }( v - + o5 {' k9 Q, @
- msHcCount++;" R+ Y( v" D1 ]( q3 X+ J
- 5 h5 R5 W4 T h' e9 q6 O
- }
" l' ?% y7 o) `& v: I) p1 n
. I6 r/ N' N( o1 w- }4 u: |6 d$ y( s+ W2 c
+ y. Q% i: X* N5 {$ M8 a- static void OpenTimerForHc() //打开定时器$ m* y }0 @! {# Z
- - h5 W3 s+ m" l0 y
- {
3 \5 g' o' r) U* d. j - 0 A- D. b3 f9 T9 @" P+ u5 X
- TIM_SetCounter(TIM6,0); //清除计数8 j7 ^" w Z6 ~
& N2 |1 w7 ]% a/ C2 H- x( j/ I! E- msHcCount = 0;* b4 j8 b0 ]4 p$ i9 t
- & G* j j$ C/ B2 O. {
- TIM_Cmd(TIM6, ENABLE); //使能TIMx外设
( {7 z: k4 `! {0 M6 r1 t - , t' ?) V* E+ A2 N
- }( J& @, H/ z# r9 | @( h: s
3 N# V. e2 z* R3 E" E4 A! A' v# T5 f- static void CloseTimerForHc() //关闭定时器; Y) O/ I+ q$ z7 g5 n
2 j0 p+ u: a, Y0 t" ]% P5 {5 x5 \- {
$ d, ~) u' q# n4 D8 w& m$ ?
- l4 p$ a& U2 ?8 r- TIM_Cmd(TIM6, DISABLE); //使能TIMx外设
+ e% m: C/ i9 X/ P" q - / ^5 l* C- p7 P/ Y5 H9 Q% |
- }
6 L. T9 G1 t# e6 X# r - . v+ q1 ~, ?/ V+ t O4 l. D
- //获取定时器时间7 c! h( a, L( U3 o
- 0 X8 N( Z1 ~3 k
- u32 GetEchoTimer(void)6 P" v/ t* m" E: f, I- F
- % M( Y2 n( @2 H6 W$ K# j. b
- {! _/ v6 a+ U2 {! f
- D& S& z( u% K- h4 N- u32 t = 0;9 Y7 l; X# l. h' n) p/ g7 C
- - D% q, ~# L9 ]4 J
- t = msHcCount*1000; //将MS转换成US
6 d% ?6 {) X- M- E
3 D" K7 o/ B+ l( Y& @4 o- t += TIM_GetCounter(TIM6); //得到总的US" P2 V2 E7 S, Q" U9 {' `; d
- , S1 H' p, g( v) S& V4 o* O
- TIM6->CNT = 0; //将TIM6计数寄存器的计数值清零
2 o" Z# x4 O/ d
# q. K2 b- B4 y% L- return t;5 l. o) a- q8 L- g
- 3 o% `( T6 S) P+ Q) v% m9 V( V1 H
- }
$ G2 `# J% S- u9 M( _5 q4 C
! }8 f7 o( ^1 ~' R- //一次获取超声波测距数据 两次测距之间需要相隔一段时间,隔断回响信号
& O& \, a1 a3 K4 I' Y3 ^
% i: A% b8 M7 o! k2 `8 c- //为了消除余震的影响,取五次数据的平均值进行加权滤波。
/ G# n* A+ r- L' J6 T
6 V: [$ B4 M0 n! @1 Q- float Hcsr04GetLength(void )0 B& ~( q! _3 T, q" P
- & L; Z% B$ F( M4 @. t/ o! w
- {' U& \$ r' d/ Z% c; o* L
7 B) c/ M% O7 f$ G8 O- u32 t = 0;
: q8 U. _: t' ?! o" H+ u" Z- e; W; ` - , d0 Q. _2 R5 L' u+ z
- int i = 0;
; E) H% f5 H0 g' J, @/ n
$ ]5 D( W# l8 V3 o( |- o: M- float lengthTemp = 0;
4 T1 m8 D( @& _2 |% a8 U3 x
: [! C; U: h. V D/ y- float sum = 0;
n2 [: q# O* \& u. d. F7 `# z! m - ( { F4 ]! u9 r* n }) m/ h# J) F! H
- while(i!=5)
; Y; ]: l& R' \1 p7 ? - ; K; l3 U# f2 V. I# u6 R
- {
) `* M, p3 P- h% D$ _
8 `0 c7 I7 e0 y$ v! n- O, ^- /*发送一个20ms的脉冲*/
; u/ `# ^4 o$ w- P - * m4 Y6 h9 ?! b# o
- TRIG_Send(1);
- F, M$ x" b# J) N* _; a
6 n: f: V: `3 H- osDelay(20);
3 [: e" J2 j# w- {2 ?' ]. M - " {6 }! V6 a' V$ H
- TRIG_Send(0);- ^0 D" L( ]6 h
4 l% D- b1 u% f1 D( a& z( [ L- while(ECHO_Reci == 0); //等待接收口高电平输出(超声波发出)' D; T4 c, A; j* r
- " ]0 L) N/ ] H' A, e! c
- OpenTimerForHc(); //打开定时器6 G) s% B' j, r- d' h* H
& H# e: f5 I0 M3 z: c- while(ECHO_Reci == 1); //等待超声波返回* m. F- J. t5 L
5 A( q* B& d4 p, ^$ _7 a- CloseTimerForHc(); //关闭定时器4 e/ ~0 n2 v+ n9 N3 U
8 z, h/ B, N( x- t = GetEchoTimer(); //获取时间,分辨率为1US
& X3 t2 b# m3 P( E* Y3 } - ' @/ f h" z" I" V/ w
- lengthTemp = ((float)t*17/1000.0);//cm4 p& g4 X+ w& H. B1 o/ K# O3 `
: t4 h$ w9 ^9 b& s- sum = lengthTemp + sum ;% @. ~9 J$ g/ ?# H
- / L. e7 h# f' z# L5 Q
- i = i + 1;
0 n4 ]5 O' [! c# G7 y
' u3 a7 g& }( d$ z( c6 V' R- }
# Y+ i3 h; c! p - ! i) M- @* o x3 q! I
- lengthTemp = sum/5.0;
; z. D: |* b! E. L `7 f
! D( d( @) u% A- return lengthTemp;
1 n- A+ H. e( r0 Q+ I% H/ J
P0 k/ i- N. a% X7 r- J3 X- }
复制代码 4 ?3 W( |! [9 ]: U; D% x- V
C0 c6 o" I$ n5 G" S
|
|