|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
下面是关于stm32驱动超声波模块的一段代码,有需要的朋友可以复制参考,希望对大家能够有所帮助和启发。- l8 ]5 A: P! ~
3 i5 ?9 }1 a3 o8 I$ g+ ?5 ~8 L
0 V3 D+ q5 G7 r- p7 Z
7 \/ T+ M# V/ U" ^' @9 J7 N. J$ S4 d
! S" v9 W" w$ e9 \% p# Q% X- #define HCSR04_PORT GPIOB: |) v; \+ [6 ^
- 2 \ s4 e6 q8 D2 B# g1 p& h
- #define HCSR04_CLK RCC_APB2Periph_GPIOB' o( T0 ]5 R: K ^
' t$ S+ F# b$ U0 ^# I5 ?- #define HCSR04_TRIG GPIO_Pin_81 i* x% Z" j5 S+ {6 C
. M7 k+ |7 X0 z$ y- #define HCSR04_ECHO GPIO_Pin_95 }9 D. Q5 s- R* s( x+ M
- ' R0 B# i4 G, ?
- #define TRIG_Send(n) do{
1 e% x" P6 h9 l( P% l4 k% f
8 h4 a* x/ A9 s' q2 k- h, @- if(n == 0)8 Y/ ]2 r! {& A
- " S5 v8 L. |7 h) K
- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);; {1 i. ?' W! e' |% F) J* k
- ( V h( H# R$ g8 O2 u; Z' C; q- c
- else if(n == 1)
" l( F; p9 U. O- d. b+ W9 Q2 H - + z0 i3 t5 o5 D
- GPIO_SetBits(HCSR04_PORT,HCSR04_TRIG);2 Z2 H- Z' U$ T0 o9 \8 W, H
* S8 A) c0 o/ q! V5 R/ ^9 ]- }while(0)
7 s# o* x9 |# q4 K$ ^
: r3 `9 J$ \# J8 j0 @% d- #define ECHO_Reci GPIO_ReadInputDataBit(GPIOB,HCSR04_ECHO)
8 }1 I) V1 Z* ~. W$ l J# _
- Y8 y* Y% D" V0 c D5 y7 g" F' H H- void UltrasonicInit(void)
3 P# ^- m3 L4 P5 s# }& h* h - ! }2 i0 L$ a' E8 B( a! V3 d
- {! D* H1 R! ^0 }& k
! a1 h. _. b; F/ }; y! ]- GPIO_InitTypeDef GPIO_InitStructure;" O7 U# P# O6 [2 b$ I8 X
0 K ]" x3 [. e- RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);
6 I! i E: R5 r! }1 S9 K. M - b/ y! @) c: V! W! l
- //IO初始化( f! p7 c/ r5 Z1 g
- 7 L% X, f& B/ e" _, T: y: n
- GPIO_InitStructure.GPIO_Pin = HCSR04_TRIG; //发送电平引脚6 Z# M2 z+ ~& Q; P
4 i6 u) i, [7 [! D- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
7 Z- @4 ^) I# U% k5 b: E9 T4 N
2 U8 w ?/ m" l* n- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出" O4 Z! g+ f. Q8 y& e) f
4 Y/ d# E6 W1 P& i# P( [- w- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
. h% N/ }/ ?" M) W
' W, |) C7 k' J, a( |- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
. q; R- O4 f) P& g! F - $ N/ c9 u! p1 C; \3 h
- GPIO_InitStructure.GPIO_Pin = HCSR04_ECHO; //返回电平引脚' y/ V" G' {8 f( T1 Q. u W
7 {: D4 Z; G4 A6 `# f" p- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
; c; r' k8 B9 p" z, d
: U0 G; Y3 L/ I( @- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);5 U( W" ~& |$ {7 n7 q0 ]9 l/ A
( H# A4 q3 H. l5 `+ x# I1 [- GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);
e1 p/ C G: x2 p7 ~9 l2 O d6 N - . K' L/ {: j" q% X
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //生成用于定时器设置的结构体
' A7 q: t/ D& m$ Y/ G3 C$ f
6 t5 @! d! y# T4 W# |4 N- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //使能对应RCC时钟
1 I! V% q* {8 V v. C& ~4 V( L
0 z7 ]- Q' Z6 I" p: J8 i- //配置定时器基础结构体
8 Y% n% R9 U6 p
- z) ~; W& y' [- TIM_DeInit(TIM6);* ~. j- [5 V8 a% u6 c- `
. g" w" E% k7 {" Z/ T) S9 }9 M2 @- TIM_TimeBaseStructure.TIM_Period = (1000-1); //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到1000为1ms
; R2 f8 |* g, q" K L0 a
0 V( Q% N. ~. c* R- TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //设置用来作为TIMx时钟频率除数的预分频值 1M的计数频率 1US计数
$ i1 V7 L y" Q6 {7 l/ k9 L - ?' `! v+ q: ?$ ]
- TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//不分频4 x# k: h" O: u, w3 C' l/ f
; a3 z! y: q- N- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式8 q' z; o, ^9 k
1 D1 G0 ~. P# _. I. e( x: u+ ^- TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位) e. Z B7 C4 l S: S2 T/ |
- & b }; _8 |+ N8 h. g' G
- TIM_CleaRFlag(TIM6, TIM_FLAG_Update); //清除更新中断,免得一打开中断立即产生中断5 |% W* m) g/ X2 t' t; S
- & u+ M& g5 Y- I& q* s0 q l }/ P' Q
- TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); //打开定时器更新中断
. L% A5 A" Z# X
4 U, u7 Y) g p( S! j; L# A- NVIC_InitTypeDef NVIC_InitStructure;- b3 ^' O% F8 M0 Y/ T5 I7 w/ _
- / f7 ]) t( q9 r, m. F, a# \
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
) k I4 B) F8 u( R
* O, n" a# N1 d& r0 V+ M* P- NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; //选择串口1中断/ r/ \4 H* ?1 L' y3 K
* V& D. i8 ^/ l/ ?+ K- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式中断优先级设置为1
* k. @. j) ]9 I8 d2 E) ~; |% A - + L* c1 v- W7 i! ]# V# a
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应式中断优先级设置为1% ^* O( `/ ?1 n9 `+ y$ o9 }
& `4 R2 x9 i) |) A% a$ o E- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断/ _# W/ s" E" R# z6 F
- 8 W, z4 |0 f( j' b6 _6 P; P: k
- NVIC_Init(&NVIC_InitStructure);
- [3 p, L9 k$ Z4 ^6 Q% E5 K9 b - 1 B/ e% x+ R" j1 l% C" m
- TIM_Cmd(TIM6,DISABLE);# P x1 G- r' Y; j( ]: A
1 ]9 M1 i: ~* T2 Y- @- }
& Y% v A( j+ u6 ]( L
4 T9 U- q6 e+ k5 H( D+ M* u- //定时器6中断服务程序% y0 {; V- S9 ^2 {9 l- g' z* V
. Q" A7 q4 M% ?2 Q. k, o- u32 msHcCount = 0;
) s! E! j7 n4 [- p* g - 4 V& d8 e- J% Q. O
- void TIM6_IRQHandler(void) //TIM6中断
|8 g0 Q: g- F, c* N9 L& {* _
5 d+ Z) @! c- D- {- q+ R* I4 z3 d9 Z# g
' p& W" _! n+ b( f A+ A4 U! r- if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
# V, h" m5 T* G% _2 b
5 [$ g, S+ H! p2 m- {
( ?, n" v( _+ [# f" ^ - 4 r- c: `7 G6 o8 q9 }4 z
- TIM_ClearITPendingBit(TIM6, TIM_IT_Update); //清除TIMx更新中断标志9 t# j. N6 u( Q
; Z m; c" k( @. {4 A- msHcCount++;' c y# u3 h1 b7 j% j( l
8 h: s4 C/ D Y; \# s- }! W* P( L8 s; W$ X. x
, J9 B0 O z) m7 I% _& X" h; p- }
- t* m5 g4 M& F) M) g# ] - " A# j: [" d$ t8 o7 o
- static void OpenTimerForHc() //打开定时器
5 p3 E% c7 \0 q
9 P1 U0 D/ }% m4 c4 F% n( _- {
* b4 B& i: E5 } r
B) n6 ^: c( h. F- TIM_SetCounter(TIM6,0); //清除计数
/ M* A2 u9 k$ I0 L% E - " h& p) `3 p& N0 C7 |
- msHcCount = 0;6 }* A( h8 @6 x+ ~6 U
\2 U# C1 f$ o/ @: a4 X- TIM_Cmd(TIM6, ENABLE); //使能TIMx外设+ i* r v% y1 n( O& d0 r" x
- & O7 R$ h" ?; O
- }0 m9 G$ s3 p' ?: X" G8 b& K6 C1 V( q; b
- & {) W# S. h! D
- static void CloseTimerForHc() //关闭定时器
0 o8 D0 O1 N ~$ t" Z+ @7 i - ! `- }! { ]9 v5 a8 D9 q
- {
% m7 T, z8 a. O7 m( F: Z
6 n+ H) }3 S8 B H& v/ A# d5 n- TIM_Cmd(TIM6, DISABLE); //使能TIMx外设
, [2 z, R0 m7 Q# {
6 K$ X, }' o s) z- }
$ E% [" z) ^, a/ U$ D% ~ - 1 }3 A' l0 H1 E8 {) h4 t& A% h( E
- //获取定时器时间
5 i! ?1 I7 \6 }& ~7 t( L
: r0 c- @9 Y3 x7 E& N; E }- u32 GetEchoTimer(void)4 m; J) n6 l# v" [
) E3 ]) D! W9 K- W, V- {
( d1 m, K* s$ {0 f
7 y; s2 k7 X# g% y( K- b/ K) {" R- u32 t = 0;
1 O: p) M! ?2 _8 Y- U5 g - - z- v6 a( Q4 w9 y
- t = msHcCount*1000; //将MS转换成US& T6 w. ~- e& S6 r) W% S+ K
( D8 }. C) ^3 E9 W# H- t += TIM_GetCounter(TIM6); //得到总的US
& U. p7 I( d' o5 J6 U1 N1 v8 c - ! ?. D+ P: n. f5 G0 n5 B) x2 H( i" N
- TIM6->CNT = 0; //将TIM6计数寄存器的计数值清零* G# P# S R: M4 ]: ^
" y1 b7 B9 z! K2 {( C3 M- return t;
$ {: }! l6 K) b5 c" b+ o - & B: c7 z/ L' p& Q0 y3 l: R
- }
, L8 G4 Z: {1 ?" J7 c, c
. l! N2 b7 V, f' R, w- //一次获取超声波测距数据 两次测距之间需要相隔一段时间,隔断回响信号
, S* S) D3 b+ E9 \6 g4 j% I ]7 Z
+ O$ }, B0 W- K8 x- s3 f- //为了消除余震的影响,取五次数据的平均值进行加权滤波。& N: e, ~! w1 R
- # Q' [; E0 W9 } O$ Q" _$ P7 q7 X
- float Hcsr04GetLength(void )
' k8 T' ?* S8 n2 J: X
, V8 I. R Y6 }6 ]% H- O- {$ j+ H+ M! {/ h+ @& J8 [; e
- 8 z/ U) B4 O& Z( |# X
- u32 t = 0;! @" c5 U; m) c' U) E. K& z* C1 \6 Z
- ) ~, M! d3 D6 s( L+ c
- int i = 0;
/ u4 Q+ J4 p+ Z1 T; H
; I9 `. Y# j/ m* q8 W- float lengthTemp = 0;, \ h% v* a" P5 r
- g9 m& ^% `6 m! }1 J1 A. v6 V- float sum = 0;% q) p$ `0 `7 r3 H% ~4 h
- : K, j& g ~* G$ ?
- while(i!=5)" G3 `) i( f" Q
- . b8 f/ ^* e: f
- {
% P$ F. _7 ~/ { m
* n; G+ U% G0 x- /*发送一个20ms的脉冲*/
6 u, c+ u$ c) q* B
/ h- W l3 b: T2 w/ r0 V7 U- TRIG_Send(1);
2 @: b3 Z! N$ Y; R$ f" I0 r( V& k
6 t; d4 V H" ~5 J/ d& P" Z3 c# y- osDelay(20);" N1 b# j! A* [% l4 l( Q6 c' w c
- 7 r: l6 E$ [1 E" d0 q1 u
- TRIG_Send(0);% E1 W z: u6 B' M7 v# }. k- z
! |% v' {. h5 u, M- while(ECHO_Reci == 0); //等待接收口高电平输出(超声波发出)
v9 W7 G5 d$ f' \" r3 j
& q9 ^0 |" F& I- OpenTimerForHc(); //打开定时器, Q' [" z8 I& `7 O
% h8 |9 w/ P; u ^5 V i- while(ECHO_Reci == 1); //等待超声波返回+ x7 G; s# P% e- |# |; y$ }( Z
- 1 b: ~0 B* p' F2 f1 k/ y
- CloseTimerForHc(); //关闭定时器- H3 I, z* e& M) y# k( a% H
- 7 R5 j4 J7 s3 ^4 f
- t = GetEchoTimer(); //获取时间,分辨率为1US
: j1 |% @- \" h8 W* C# z. G$ O
1 D, n Z& ^6 s) Y- lengthTemp = ((float)t*17/1000.0);//cm" `, \; m) z; N b) t5 M0 G( U
: t- ~- M( w: [- sum = lengthTemp + sum ;$ v- ?; i/ G; V
- - N' V! U4 g6 m1 E7 Q8 v
- i = i + 1;
& [5 G0 M/ l! U8 P- ~ - ) F$ N# _+ l3 V9 D
- }
# h# h9 j8 _6 X* \+ H+ P4 O( Y - 6 b { ~. t5 ~! A
- lengthTemp = sum/5.0;
. m* v5 G/ y9 ^$ s+ F - I9 u6 O1 u, N/ t
- return lengthTemp;
7 ~* v! {5 h% }" _* @
2 S W; ~$ ?/ Z* u: X% X2 ?+ J- }
复制代码
- w9 D1 `2 r* V$ ~5 r3 }& ` y" C. T7 u) o3 W6 g
|
|