|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
下面是关于stm32驱动超声波模块的一段代码,有需要的朋友可以复制参考,希望对大家能够有所帮助和启发。
1 w; R6 |7 R+ w: M0 _& R+ ]) g& m2 Z! a! @: Z: Y
7 r2 U8 F* J% _4 X
9 ?8 [7 W* r) \0 a. g
2 [" O* x1 ~- w! H- #define HCSR04_PORT GPIOB* X* _# a8 H6 h" H, {& f
- 8 w2 f+ e2 b% Q/ ?
- #define HCSR04_CLK RCC_APB2Periph_GPIOB
: N$ E5 _7 o0 V: y) R* D
/ W4 o) y) p/ W) a5 Y( T- #define HCSR04_TRIG GPIO_Pin_83 Y! {; D' q X2 i
- ) [- K5 L% e4 z9 }9 W, ~* Y
- #define HCSR04_ECHO GPIO_Pin_9
$ M! E2 o2 K! p( I6 n - . ?2 }! H. ^3 d5 X- @
- #define TRIG_Send(n) do{
: d6 O; B0 z& s. c4 h, N6 ~0 x2 D% r
; u3 ]' F* e+ y- if(n == 0)
: H' e, L6 l0 d9 u, |8 ]& W$ L - & {& m$ D+ Q& v
- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
2 p- { t0 f/ S, _# ?5 L& ~
; U6 y% L0 I1 C8 } h: O- else if(n == 1)
! ]" u6 C$ W3 h" M: m3 g# |
! T8 O: y! I- d' V6 \- GPIO_SetBits(HCSR04_PORT,HCSR04_TRIG);
- K' K! Y& V: P7 @$ Z' k9 c - 6 A, x+ E; b7 T& D& d
- }while(0)1 e4 }6 M) l& o+ a, m* ^- W
- * z, I) Z J- Q* [$ W
- #define ECHO_Reci GPIO_ReadInputDataBit(GPIOB,HCSR04_ECHO)$ v* A* a$ K# V: R2 T$ z4 u
: R# c0 |% @- R, k' X0 U0 @- void UltrasonicInit(void)- Z+ L5 Y% q% b0 @6 g
2 v. E/ D( S! k1 ~1 X% k- {! G3 F& E' q- X* n& r
0 c; l7 A* W" B& Z, i4 v( B- GPIO_InitTypeDef GPIO_InitStructure;
3 U G+ y8 p6 N( `
7 s3 K3 b+ i% d' N P# E- RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);
6 z: i: a' }* k' D, W3 M4 n - # v, v4 r q2 V& I6 Q
- //IO初始化
) j' `1 {/ w4 v9 y* Q( i: K8 g - ( _* G( ?8 n: {2 S3 k. s0 {; f
- GPIO_InitStructure.GPIO_Pin = HCSR04_TRIG; //发送电平引脚
3 d Y, f8 k1 W& D: D
- @% h- _% Z" h& I6 f0 A. f- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
0 {& q% T$ Y& P/ r! z* `
6 u) F* M# E3 ]5 M- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
/ u) E0 e8 L+ M2 {& K6 N
5 `8 I" k8 t4 x8 s9 v3 \. l- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
4 X$ k4 c M8 p+ p( ] - 5 z0 i; E& w& @+ [7 Q, ?5 ~
- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
- q$ `+ l; t5 w5 W/ ~ - * M7 ?# E+ D7 m( f- E: H Q9 }& N- f
- GPIO_InitStructure.GPIO_Pin = HCSR04_ECHO; //返回电平引脚6 b4 i& A/ O6 `3 Y' \# b
- ) E4 P" j( H* B+ b+ B8 s
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
$ i% n# D- _* V: D0 r
3 O; X0 `6 G9 `+ g+ U( D( ~* ?- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);; M; l; o2 L6 M p5 J9 A
: Q8 X; K: y+ l; d0 I- GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);2 F" J) k0 Q0 {4 ^* O3 f
- 6 K% F( _( s) {" f
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //生成用于定时器设置的结构体
+ M$ U8 A/ l3 M6 q% r) T E: ~ - / J! p: Z8 Y+ X& ?) `
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //使能对应RCC时钟
7 O3 T. h' D7 |' F - & B. z, B: s$ ~- v$ E$ t& h
- //配置定时器基础结构体
9 z! d: w1 M. S, ?
1 @$ ^+ v! t7 |$ s) y- TIM_DeInit(TIM6);
% s* a" ` Z2 Y# @% Q8 E& Y2 L - ( f: ^. h# f# f5 }! q
- TIM_TimeBaseStructure.TIM_Period = (1000-1); //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到1000为1ms
) v% k0 w; t. @8 u
6 k/ @$ u, O1 z) i' ?0 `1 x8 s* Y- }- TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //设置用来作为TIMx时钟频率除数的预分频值 1M的计数频率 1US计数
7 h- X8 G' K1 `* f. P. ?
/ |7 z( S& n- U# P$ m4 E! E- TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//不分频! K3 z' ?, d7 h- H4 }
* R# X# q2 b, r- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 [8 M% ]* L W# ?
- % @4 L, \# k, g
- TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位% c$ j1 `! J% [! n; M" l
- . v! j* R% I2 o' z2 j
- TIM_CleaRFlag(TIM6, TIM_FLAG_Update); //清除更新中断,免得一打开中断立即产生中断
/ L, e: Y3 A6 H3 V - + b0 B2 L9 F: t/ X7 T# O9 B+ h9 F
- TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); //打开定时器更新中断
- U4 I' l5 Q- `
# d) k: l4 {7 x+ T$ [5 L- NVIC_InitTypeDef NVIC_InitStructure;+ D9 _; r7 U1 Y4 C# z7 _) V: I$ Q
1 f6 R( k3 U* E- U- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
4 n8 E' @5 v/ o0 z$ V3 g - , S$ t8 P6 ?0 H! A4 @
- NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; //选择串口1中断
0 d$ | U% g5 Q - - |* _4 x! t) u+ s) l
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式中断优先级设置为1! Q2 U+ ]# B: T/ U# g
3 I- L5 J! w- _- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应式中断优先级设置为1; n% _% o/ K. [, V9 `9 f4 O
: |+ {# ?( _, C D+ Y/ D1 W- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断: F# D' T! @9 c* P7 ~; X% [" B
- % a+ a1 l2 M% A* ~) q& u' m
- NVIC_Init(&NVIC_InitStructure);
# @5 ]3 B( \$ U+ C& q' I/ E4 b: k
! M8 r# C6 w4 Y: w; X- TIM_Cmd(TIM6,DISABLE);
8 l! B0 b/ s T, ?$ f. F
% E) G. T4 t" s9 F' r5 z- }
1 W# _8 s- J2 w - " p3 U1 h# @, r2 l3 Y
- //定时器6中断服务程序
; X* g4 f' O* q O
. ?+ M% B$ N- ], n# [9 _- u32 msHcCount = 0;, ? h7 n; B0 l4 ?) t) z) ^3 ]
- 6 i& s) Q: U, M
- void TIM6_IRQHandler(void) //TIM6中断
, s; ~0 Q7 ?$ Y9 e* I
) Z0 ~5 K) W3 z! v% ^1 j0 Q- {
6 d3 z/ r. A( I8 h
; B( a; `8 ~( X: m- d- if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
7 D6 Z2 F% J s) M* v% r3 q( u
2 R% F3 }- r6 z p1 `6 Z. X# P- { X9 Q% U! y" W2 M
0 Q4 c! v3 ~! x, y2 ^5 q+ m- ]5 c$ C9 {- TIM_ClearITPendingBit(TIM6, TIM_IT_Update); //清除TIMx更新中断标志
7 o) t4 w0 y6 w# }1 q - 8 {: @3 |9 m' r
- msHcCount++;5 C8 _9 k# y& O1 f) p# G) A
- : z4 s9 R$ P% P) N7 s
- }
. S" Z% R" I2 L) A) Q/ | - ) e( k+ ^1 t' R. [; ]
- }
1 X# i. P8 }* u6 f) j) \6 p5 b! K' l
# m! e/ @5 ?" t- static void OpenTimerForHc() //打开定时器' E3 ]" q# @; g1 g9 X- G5 ?
- ! Z1 {( }' B$ g) C7 {
- {/ y! g! s! J- U, @# {; n. n
. U+ X. \4 H K. {- TIM_SetCounter(TIM6,0); //清除计数 F8 C2 _9 s7 K" I
: C2 N) K& o- O* z. b9 K/ ]2 Z- msHcCount = 0;2 J7 a3 [& f) x: M* B) H3 O4 r
8 x. F% f* T% o( `' t Z; b- TIM_Cmd(TIM6, ENABLE); //使能TIMx外设0 u# r+ P2 _7 X9 T$ |. r9 s, v# n; @
- . r* T' e( m5 u0 Q' A" Z0 o
- }4 H0 ~/ W* X; ^9 _ P
- . X) F4 U) v; z1 i& W
- static void CloseTimerForHc() //关闭定时器$ r" |4 [9 I5 x7 g3 i+ c9 y% \
- : E, K& I; ]. h+ G: U( ~2 X0 {5 Q
- {6 v, K1 Y! y1 g( s9 h) }) X
- 1 }: N" }& b7 U9 |: M
- TIM_Cmd(TIM6, DISABLE); //使能TIMx外设! }. }- Z& }0 S& A9 f% y; \
- c2 B, c a$ L" H( V! m3 }
- }
8 G$ T6 {" q K! ~0 k9 e9 J/ ~' t
, k* n5 U* l5 B; G' d- //获取定时器时间
; b6 h1 r3 h- |' d! x
6 G9 h% _3 `+ u& d: X y9 e- u32 GetEchoTimer(void)7 L2 {9 k: }& u: a( y1 `
- 5 W9 l4 n6 Z" E
- {# k6 b! V% i* Z
+ ?, x' S) R1 q* F7 F8 `- u32 t = 0;. B+ I! a b1 A9 K- \
- ( P) S K6 {2 y& Q- J
- t = msHcCount*1000; //将MS转换成US
! T5 z: \( r8 r6 S
+ @) i9 u4 C' O9 m- n+ T- t += TIM_GetCounter(TIM6); //得到总的US
/ O: B- |# Z1 k( u# @" @+ M
3 f6 j; r7 r- k$ ]3 U( N) k- TIM6->CNT = 0; //将TIM6计数寄存器的计数值清零
: {2 e$ R' D B4 W$ s r - ' P: u/ ~$ G: w, r( k w
- return t;
7 g$ ]4 N# Z( Z8 ~3 r' k
5 f) O! x4 `6 F5 _- [- }
$ l+ |9 F( t$ O# |, M4 \
9 v# v: _' {2 H* t* _/ @- //一次获取超声波测距数据 两次测距之间需要相隔一段时间,隔断回响信号) f% q* m# T! m0 Z* ?3 W4 z( b2 J3 o
- - N5 v2 A9 |# U7 Q" C+ c
- //为了消除余震的影响,取五次数据的平均值进行加权滤波。! B, G9 W: L$ ?
5 ^1 ^, P" O; ~- k* c9 \- float Hcsr04GetLength(void )+ S9 P" }$ T5 F* z. h9 t: y
- s: Z& @7 W! U9 K- {
+ |2 @' U1 s; B7 r( d1 z - . n! K! w5 Z) K- _, B% d
- u32 t = 0;' m/ C- m4 f3 g8 \: x
& i/ |5 p3 P& B; v1 X2 W- int i = 0;
8 U2 {5 S9 J% u3 \7 o* t
2 K. T0 W8 p/ R) K5 K- float lengthTemp = 0;; R6 o$ N) Q6 l8 Y
- ; t. f' b/ q; ^# O Z, I
- float sum = 0;
# T; R2 {! Y* S. E3 `& L - 2 @# S' v: ~& o+ M' A, R
- while(i!=5)
3 p3 |2 y6 @1 m) C0 b0 o - 7 ~* q" T& u- v( w- h( z) o
- {( M3 t4 w: [, ` j$ g3 z& y5 d
- : [& g; T6 a3 T0 @3 Z3 Q9 T! Y
- /*发送一个20ms的脉冲*/
e; ~, `, E# a( d9 H
* a X; t# I! p4 k. z# X- TRIG_Send(1);
0 U: Z: H# V% B' l. K+ `9 P
- {5 p+ \7 P: f ?# a2 T- osDelay(20);) R0 E' z! ^! _# j% g( I+ f
2 } F9 M- i$ S" _3 B- TRIG_Send(0);
4 X4 T6 a2 ]) l0 q
' A' \* W* p( P) M6 y' ^- while(ECHO_Reci == 0); //等待接收口高电平输出(超声波发出); o' p4 ]& m V8 f% Y) F
2 B8 S6 n/ D+ K3 {1 u0 q2 _1 R' V- OpenTimerForHc(); //打开定时器
8 r' I. O3 t/ d* x5 V
$ R. V- S+ Y0 C9 A4 t2 w' d- while(ECHO_Reci == 1); //等待超声波返回4 C& p) `! \, M5 z3 X5 a
- 6 [% w& b2 H( R! ^% o# r
- CloseTimerForHc(); //关闭定时器0 r1 d3 J( @+ S
- 6 m! o( W- e8 O2 R- n1 K- a! e5 w
- t = GetEchoTimer(); //获取时间,分辨率为1US
5 Y% s+ A4 j: Y! t9 R& r - + f( d! ^. ?+ q5 S9 d
- lengthTemp = ((float)t*17/1000.0);//cm
8 S- } L1 C( @2 R! i% c
0 [3 N; \+ M7 `( {% S' l0 u2 }7 D- sum = lengthTemp + sum ;9 u; O5 E3 Q3 j' C
# K/ o- N- s6 @* @ Q, z! V- b4 i- i = i + 1;
8 x4 C) k* R- w. r0 T - 9 D' N% K2 a% S, H$ z! d6 Z
- }8 {6 r. {5 m }2 [6 g6 g# B9 i
- ; d* r! _! {7 E2 D9 }
- lengthTemp = sum/5.0;, a# p8 ^) O" u7 `
1 Y" }+ n$ h) \* I- return lengthTemp;
1 D' D7 j5 {' j0 } - 8 a: @. p+ J4 S. E) P' |% u/ m
- }
复制代码
: M+ E' A3 l* L! L: j. j9 F
6 |# q M* n! S1 ` |
|