|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
下面是关于stm32驱动超声波模块的一段代码,有需要的朋友可以复制参考,希望对大家能够有所帮助和启发。. ^6 u9 l. [5 S+ h9 j+ o, h0 P
" w4 E6 ?9 i: W" A
0 V. z \" Y- j
0 a5 w, A2 W6 [- i
5 ] f: ]( N) K/ X0 U- #define HCSR04_PORT GPIOB: y7 ^' Y' f) {8 S2 S8 _ C u# V
9 \9 W' E% H* N1 g9 ?% J- #define HCSR04_CLK RCC_APB2Periph_GPIOB+ @1 q6 {# x- A5 ~8 y: \
J, j$ L9 x8 S" W: ]4 F, e- #define HCSR04_TRIG GPIO_Pin_8
$ @, e0 Y# n# A: ? ]
2 h2 U+ K8 H1 \' s7 Z% e- #define HCSR04_ECHO GPIO_Pin_9
4 f' X+ L1 p9 \6 X
/ F8 H- U/ I' U' v' Q6 A- #define TRIG_Send(n) do{
% B5 b, [* p( [, C0 z
* P( g& B' L* [- if(n == 0)
6 ?' r( @7 i9 j
! N6 k& ^5 z. R. r, b8 `% X! k: B- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
- x( V- G0 o$ ]
. z. r+ Z( N- J; h+ {- else if(n == 1)
# \4 h# N! ^7 t P3 M - / B, o6 ]( Z# s3 l
- GPIO_SetBits(HCSR04_PORT,HCSR04_TRIG);4 ~3 `, j$ M1 H, V
- ' v/ Y4 R1 Z* e9 M1 l. y/ h8 _3 T
- }while(0)
6 A5 p/ \! X$ S5 Y0 {" T
o0 K0 s: t. w- J j! t! Z- #define ECHO_Reci GPIO_ReadInputDataBit(GPIOB,HCSR04_ECHO)3 y. }6 {- E& h s% f" D: h
- $ H! F7 a B0 ^4 p9 |
- void UltrasonicInit(void)1 E' j6 q' T5 s: _7 E. q& M
- + @! j, |/ V+ {; a$ D l/ L( I9 [
- {
6 o1 p- ?& k1 D
: \! I6 E6 n: h% I3 V: ~* U, X t- GPIO_InitTypeDef GPIO_InitStructure;8 r" W9 T; {" o* b [# D3 g
5 n+ |, c4 e2 K1 x- RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);* W" ]) E) i, M2 Z5 P) `
9 H6 A- V7 W$ W f' p) m3 t- //IO初始化* y& S' `( [9 i* Y3 E2 v
/ F5 ], L$ d( y$ a- GPIO_InitStructure.GPIO_Pin = HCSR04_TRIG; //发送电平引脚3 Z" r+ Y& O v2 I
! X4 X0 p' d5 r* D" J7 D( c- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;* V% P' R% N" u7 p0 i
- : {+ o+ r1 E/ Q: S' P7 V. L
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出1 ]* p: I% Z! A6 k) Z
- # E2 g3 K% v' o/ k) n( F* @# ?
- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);2 I9 W) `6 d1 W9 d5 ^& S
- 5 U& b5 Q' f# ~! z5 }' q, U
- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);) t, H1 r& @& j
2 \) {/ K+ `- t0 C# K/ h- GPIO_InitStructure.GPIO_Pin = HCSR04_ECHO; //返回电平引脚$ i( p2 `( G& u9 _7 V" G
- ( g8 L: `5 [2 @1 [8 |+ H
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
8 R8 g' w0 o/ z: }. b% |5 v
! N8 |; a0 q* w- f2 h6 ?- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);3 o' l' j3 b3 n2 h
- 8 [# M$ @* s9 e! R! z. a
- GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);
- N, e; _( |' ~0 q
- Z! d7 o. e8 ]) a; W7 r! ]- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //生成用于定时器设置的结构体
4 O) ?; L8 s0 K5 f5 j* r" R - Q+ }8 A8 V; a: w
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //使能对应RCC时钟5 K3 \% h2 [2 m: M
- 1 o+ Q) j) G9 K" ^; L) s: X2 v
- //配置定时器基础结构体
' Z' M, v% k1 I* k - % p% T- f6 m& S
- TIM_DeInit(TIM6);
6 _8 }$ B, d4 V$ }! }) G9 G6 q
( S# L! r( [1 F% O8 \- TIM_TimeBaseStructure.TIM_Period = (1000-1); //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到1000为1ms
4 _, c, F2 Y) t4 b# d2 m v
1 \" X/ y6 \8 g7 ]- TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //设置用来作为TIMx时钟频率除数的预分频值 1M的计数频率 1US计数
' w0 d) g% k! Y2 m$ u - 0 B; q. {7 Y/ M: ]" @; }; Z
- TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//不分频
+ w9 d7 E( i* Z j$ e* G, Z% c+ u - ( x2 p6 \% |( ?2 k, F) ^% Z
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式" } T: H5 s0 u8 L0 M5 K/ j
- * P7 z& _) _, {8 F- N/ a: c7 r
- TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
! A2 X& x& d7 ^! c2 }* o- W: B - 7 F8 D+ ^8 X0 S5 F; O
- TIM_CleaRFlag(TIM6, TIM_FLAG_Update); //清除更新中断,免得一打开中断立即产生中断
* W5 H; f+ _! w# k - + n: I5 J* b! G5 Y/ f9 ^
- TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); //打开定时器更新中断
7 `, Z& M* r4 J0 a) B2 I+ L6 ? - ! K6 w. @8 g% e( `* X2 @( y, X' z
- NVIC_InitTypeDef NVIC_InitStructure;! H0 V. R- i; R$ Y1 N( M, L8 H( ]" Q
' D7 x+ }; y0 w. q- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
" p& T( j$ R' @. D8 W& U
: A) U3 I0 S3 p, m- NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; //选择串口1中断
- W; ~. W; t0 Q; [, x
2 [9 B( z9 d; `2 L# M- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式中断优先级设置为1
2 F, v& t% u6 r# y - 4 r' c$ u: q; s% q1 H3 ~
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应式中断优先级设置为1
; }8 w6 n+ l# H, R. U - : n3 T- F, v; Q) R9 `6 @
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断% c6 @3 W1 L+ y1 w3 Y
- 2 k8 N6 M+ i8 q
- NVIC_Init(&NVIC_InitStructure);
' l1 J7 ?! _7 U - # J0 s. |: x' c, Z5 _9 d
- TIM_Cmd(TIM6,DISABLE);
c4 h! \% J* h9 r, ^ - % e% n8 I0 Y2 U5 q0 x1 ?
- }( h4 \! ^1 R8 @" D6 S
- . i( x; ~6 ]" @" \; j
- //定时器6中断服务程序
5 e4 `+ x% Y- Z6 J. I
; F+ Y, t* ~1 f; t9 H- z- u32 msHcCount = 0;0 S' q6 d, l7 R" ]& {7 g
- 1 Y2 p+ n: a, A" I8 E3 M& g. M2 a6 w
- void TIM6_IRQHandler(void) //TIM6中断. m8 X( J" k# K9 J& l
- ; ^' p8 `1 R" q( @3 ~0 R0 L8 q
- {" `/ }% y$ g, ]2 i8 O
( } z, E5 W3 ~8 U( a" I4 N- if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
' H* i. a, r" A - + K6 L- `: ]" A6 Q7 ^$ n
- {
. t$ d# ]& R1 [2 c9 | ~+ K - & Q# `( c b% R1 `& P0 g
- TIM_ClearITPendingBit(TIM6, TIM_IT_Update); //清除TIMx更新中断标志) g5 c7 |* m5 I1 C
6 C4 u7 q" s( o K* M3 [- msHcCount++;
( Y+ _% k" g# x4 W8 ]$ P( O. { - ~2 c$ E5 ]( Y1 v" R- y8 D
- }5 Y1 x% S( J6 e' M7 I5 G- d
9 | ]; i. ~/ `- }+ G2 t* c0 Z* C% h* M; I
- 0 F0 J7 A4 u8 ^( t3 L$ H
- static void OpenTimerForHc() //打开定时器
M* ?5 O, i( [- N: Z
8 N1 q- U+ Y7 u; r# Y! M' V- {/ i- B% s# k1 S* a4 W; U6 ]
' o9 q' K; r$ `% `6 e4 f- TIM_SetCounter(TIM6,0); //清除计数
5 W- f2 _* E6 n+ o! B9 ~
: U; v! F6 J0 N7 a' L- msHcCount = 0;5 N# F# d" ?. S, ?7 P& @& ~
6 e7 Z' }3 y! G7 Y1 L5 ?; Z. z# j- TIM_Cmd(TIM6, ENABLE); //使能TIMx外设. m# z# ~9 O6 }+ V0 \# A
! m$ m$ T+ l. B, r& s6 @: D8 r+ D# d- }; l6 w+ R; O: J/ g$ Z! B3 G
1 S' ?9 J& o$ h1 I m- static void CloseTimerForHc() //关闭定时器
3 d) x3 d2 m" w2 l, U9 R - $ ~6 G$ y# I& ?# Q5 W! y; s9 Y
- { Q- ?4 G1 Z2 F7 ?! F( u6 H
# {: i; ~" ?" H1 ~$ s# m9 F9 L- TIM_Cmd(TIM6, DISABLE); //使能TIMx外设+ S1 Y( h- `3 H* z6 |6 `
- 0 b; i, p0 @ E) r% R8 P
- }. Q5 N! [+ f1 K8 w ^+ e
- 5 }# z$ {0 y' S6 V' T" P0 d2 E9 q
- //获取定时器时间2 a: |; g) p( A! j
- + y! |$ s/ T N* d( q3 u/ Y
- u32 GetEchoTimer(void)
0 N, @! |5 A- k
2 Q" d5 i0 T# e$ E- {7 d# Q U% U: G4 |
$ k1 w7 G/ `2 Y q. q, @; f- u32 t = 0;4 h+ k A2 O9 U+ ~
- ; D7 P& F9 e: K8 h% F, F+ r
- t = msHcCount*1000; //将MS转换成US3 G, \0 u( b$ U5 n+ g+ ?
# ?. z/ L# E+ q$ B9 _ t- t += TIM_GetCounter(TIM6); //得到总的US
& F% E4 `: k: z6 ~, X - 3 U5 w" w- G2 H7 K" R# Z$ _6 {' G
- TIM6->CNT = 0; //将TIM6计数寄存器的计数值清零
0 h- Z; p& V3 U6 T - ( r) _& j+ I( L1 J0 g+ k
- return t;
) H- R# s+ F7 o7 f) w9 G q0 ^ - + x I( c3 G# ]4 q2 ^5 n
- }# o- b& P& p3 U* Z9 P; B: o
- + c: B0 l" M% S: T
- //一次获取超声波测距数据 两次测距之间需要相隔一段时间,隔断回响信号% M$ [6 G" J6 M; W
8 `# {1 Q- Q# p. H3 m- //为了消除余震的影响,取五次数据的平均值进行加权滤波。6 ?; L N5 Z5 u! t, G
. t5 s4 e, f% F7 @% }5 i& J- float Hcsr04GetLength(void )" I, o/ ?/ |, m' F$ o% g. v; ?
- " \2 ^: u. `% n( l
- {! A( a# E$ Z3 X1 s3 i$ k, [: y
- / C. V/ j$ w1 _$ o
- u32 t = 0;
8 K, B! F# M7 z3 f! W7 [ - 9 y: B8 i/ L0 ^
- int i = 0;
3 E( J+ [& E7 B" b
+ e( ]+ I& M- I- float lengthTemp = 0;3 f! f6 o. }, n8 u
- ' q5 o( y' P, h8 k, Z
- float sum = 0;
5 k' l2 ~0 r* ?0 t s. F r - 5 M# k0 f! Q7 g3 U$ e7 w+ k
- while(i!=5). ^5 v& X+ `3 F8 P0 v3 U/ @/ V
5 C( @4 R0 E0 @& ?" c( c) b5 P- {( }, m& y2 k8 w. x
- 7 P/ F( b1 x& z3 M. n. @/ e
- /*发送一个20ms的脉冲*/
! r3 _2 v6 ]6 }2 C7 A3 \% T - : r. G2 `( c4 P4 t
- TRIG_Send(1);
* @2 J% k, ~8 d! Y) @3 d5 i, c& g - ) E% m- D y7 R R( L9 r
- osDelay(20);% X9 A' L# c. R
- + S; P4 U! c( l/ n% b
- TRIG_Send(0);; m, H% T. I$ o! A# z0 {7 p% O# o& M. U
& N4 ?) P- D$ u. u% y; Z( @* `& ?- while(ECHO_Reci == 0); //等待接收口高电平输出(超声波发出)$ Z. _ g0 s3 ]% Y) [7 P
/ C: s" s- C3 M- OpenTimerForHc(); //打开定时器
1 M( e; b w2 [; |; f% h, L - , s, G. T3 c# B* V1 y
- while(ECHO_Reci == 1); //等待超声波返回
) ^+ T( R# r& g0 C9 p" Y8 J7 g
, B P @: i) t! m5 |1 U: R& V: }) M- CloseTimerForHc(); //关闭定时器
: R. A7 j! d2 g% { - ' N8 l0 E3 m! U! c1 C6 W2 k6 |
- t = GetEchoTimer(); //获取时间,分辨率为1US
' {7 S8 ]1 N5 H0 B" z
W" d' m C5 @& ]( w& } h- lengthTemp = ((float)t*17/1000.0);//cm! i8 q% g' k/ f6 m# l
- - s7 s/ ?5 O$ n1 f( d, s) Z
- sum = lengthTemp + sum ;
( X, ?$ g# Z, C! d& V) R' u - ) T5 \2 k# N' O2 ^% X
- i = i + 1;
- m) t* u# S/ J: q. V9 q* B9 A
0 x( h6 s# x1 `+ p2 s- }
( Z- F+ u' g+ \* G: c, Q! F8 F
% _" N, A/ Y! a9 [2 R- lengthTemp = sum/5.0;
- ~- M1 o8 R% H/ B4 O. I
5 U- H6 Y7 d/ f1 y/ c9 i# I- return lengthTemp;+ l- z' K) N3 c" u6 L2 a6 X* P
- 3 h& Q" j* o) K
- }
复制代码 & }+ E% e5 w5 O7 J3 D# B% A+ z
( {6 B' f+ {, Z6 v7 s& ?. _9 H3 G! ? |
|