|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
下面是关于stm32驱动超声波模块的一段代码,有需要的朋友可以复制参考,希望对大家能够有所帮助和启发。
& _/ |5 ~% P# ]% s: A E
4 F- U6 }: b- i; K+ G% R
8 s4 \! ~7 O4 X$ N1 S) K& G
% E( Z# {6 t7 P6 q0 c! J
0 V1 _0 V: o; f" c# D) x8 a. c- #define HCSR04_PORT GPIOB
: u7 M0 X/ d& t# A T0 @ - * w2 Q. i$ Q/ |
- #define HCSR04_CLK RCC_APB2Periph_GPIOB
$ i% z2 ?# W3 q
7 v$ ~6 s6 V3 E: g" ~; y- #define HCSR04_TRIG GPIO_Pin_8. o1 k8 g, x4 O, X
! X; J d7 @# A9 m" L2 U- #define HCSR04_ECHO GPIO_Pin_9$ ? D1 i: G+ @: u5 }! c1 d& E( V
- / h) ~; H8 D3 V( O ^
- #define TRIG_Send(n) do{
" @, f8 l9 V7 P7 G0 ?5 l w3 z
4 Z6 ?/ g3 q. r( H: V- if(n == 0): T ]( f3 w7 m* a$ @
- ! n8 d& o9 k/ t
- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
% w" e) I& q% }9 A+ h - - \7 S. J9 L7 L( f1 p v- ?3 J
- else if(n == 1)
( G+ B# L2 f! _; P& c- s
7 r5 b& X7 j4 k6 f! z* n- GPIO_SetBits(HCSR04_PORT,HCSR04_TRIG);
7 @- w5 v+ N- ]: j1 _4 N) {4 q
C9 V; h) f5 E! f- }while(0)
5 s% `* v' w9 z
" c; e) w! x2 e! Q1 c7 q; u' I4 P- #define ECHO_Reci GPIO_ReadInputDataBit(GPIOB,HCSR04_ECHO)
5 T" z+ i2 n* d6 y
' x! u& `& L7 i/ e8 i. I/ W9 [. G- void UltrasonicInit(void)" s0 n: T% d! |& w- Q( a
- 2 b' m. D$ D5 C w- t0 c- h# y
- {* m7 Z9 [* K( o% v$ S
- % C( k4 a& F5 e4 `- W/ X% }5 q& C9 S
- GPIO_InitTypeDef GPIO_InitStructure;
* e4 g9 Y& Z/ S# R' }
, J/ l. }$ ~3 e1 p- RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);. z; n% d$ K+ c6 [
% J9 Z3 j8 p3 C- //IO初始化% w+ A( Z' S1 e; z8 Z
& l" D8 p' e2 w7 \5 d- GPIO_InitStructure.GPIO_Pin = HCSR04_TRIG; //发送电平引脚
3 Q& `9 x6 Y/ F& Y6 X& }( o- U - 3 t, G$ @ M' X4 Y1 A ?
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;6 d h! ?% d) g' \5 A- E, ~5 U
3 l+ F, d/ f5 l' U) s- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出& ?( z( F, }0 k) K4 c1 t
* G2 _3 [. c( }& u2 @' a- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
* s0 J- r. I* U; n0 e - 6 R; E! [) B0 V
- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);4 ^( C. d, o0 M! S: f* a
- / E+ i9 p5 M: t. Y) E
- GPIO_InitStructure.GPIO_Pin = HCSR04_ECHO; //返回电平引脚& Z$ J. `& b) `- i
- 9 N+ j$ y- G( ~
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入8 R# i- z; U) ?/ V6 n8 b: J
4 U7 g- {6 K6 w; W4 N2 X- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
: {( Q& C2 @& M2 r: s/ h- z9 o
0 f7 t/ F$ @8 |6 |: {- GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);
% A' I" M: ]3 \. }
+ ?' F5 g) \2 g% P8 V2 O5 L- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //生成用于定时器设置的结构体6 x. C5 |! v/ W/ L+ X1 n. K
+ k! q$ b+ g8 P7 T' b+ G; s* n- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //使能对应RCC时钟3 T6 J; z' _6 U+ j0 d" M. ~
+ `$ }2 I5 A6 B' X/ F- i- //配置定时器基础结构体
' `; q2 S1 M6 h5 q/ K1 z) X - 8 D" f8 I$ j5 k& a3 B% O
- TIM_DeInit(TIM6);( @7 O6 l0 R5 g5 l2 J, o5 q
" x, E+ ^) y7 }1 S" M; w- TIM_TimeBaseStructure.TIM_Period = (1000-1); //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到1000为1ms
% |0 l+ J2 q+ @. N) |: Y - ; [ F6 V- Z4 J
- TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //设置用来作为TIMx时钟频率除数的预分频值 1M的计数频率 1US计数& A3 u: l5 [8 P/ B9 A3 J: F$ W
9 ^" Y8 M/ ?- l; x0 u4 q5 ^4 f- TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//不分频+ i& H H+ r, c- g: o1 K) X. I
5 k; l: a8 @8 I1 b! l/ f- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
1 C; F# A3 f3 L R" y - 0 X5 ^* T' V8 _* _: |, T! g
- TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位8 |3 Q0 k) \+ k# q/ ^
- 5 a: c' o: s7 q: X D7 D; b; F
- TIM_CleaRFlag(TIM6, TIM_FLAG_Update); //清除更新中断,免得一打开中断立即产生中断+ g, j, H: p1 c; Q. t& J
- + [( d' {( A0 e4 {& h' N0 B
- TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); //打开定时器更新中断
( V; `* v- N9 J1 c$ u - ; v1 f0 r6 G5 M: o# m
- NVIC_InitTypeDef NVIC_InitStructure;4 D0 D3 `4 T* ~7 x$ E' |0 K
- " c; f: l6 y' P, I, m& D
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
5 w5 k, l! m1 C% B
7 q% W1 o% j6 z- NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; //选择串口1中断
( A! t3 e7 h2 A/ L; [ p4 J3 s: S - 8 W A8 U& f7 H- t, t Q- X
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式中断优先级设置为1
$ N8 C- l' r2 H% S - ( E# y8 c- P- O) [
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应式中断优先级设置为1, P: E& G5 R) r
- & W+ G$ _8 X8 v* _
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断/ |7 ?1 Y$ t8 K- w h
- $ A/ k0 m6 L* j; k
- NVIC_Init(&NVIC_InitStructure);+ B6 F; M; ], H- K
- 1 s/ `' m" H# y- M& C. s; X
- TIM_Cmd(TIM6,DISABLE);
9 `3 a! ]* E& Y9 O( X - 1 D- ]1 c c0 ~1 Q; h" m) D
- }
& b* s2 @( ^9 \
/ @: `" H0 x) c! _8 S* Y- //定时器6中断服务程序
+ |* ]9 n' D% @1 Z3 |
1 j S) O7 K* u0 j7 n* Z1 m- u32 msHcCount = 0;1 F) y7 @" `: H; P* n1 {! Q
6 G8 R4 J1 ^! Q2 y- void TIM6_IRQHandler(void) //TIM6中断
3 q" ^) }' ~" Y
. s/ T ^# q7 z' p- {9 r1 T, ]4 T' [% {
- ! A; B& Z( @ }8 ~ H8 }# D: o4 n
- if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
: x3 A3 e6 [" {6 G7 A3 l
+ J" t/ c; w3 \7 c! |) g8 \- {
3 X' b {7 b( M% N# S
; x$ X2 [$ c; `: z) B1 w- TIM_ClearITPendingBit(TIM6, TIM_IT_Update); //清除TIMx更新中断标志
( g8 ~! r$ b: v% u/ m! e - 6 ~9 W1 i' K3 M- T8 b* k
- msHcCount++;5 f3 [0 |: ?/ l/ j* t" l( n4 h. l6 U
- * {4 K {9 b [' m
- }$ d5 X1 P2 z! b( W& I9 i
5 e/ P9 I7 U5 }# @+ f7 }6 M6 y- }
5 Q6 p- i; T- J/ j3 b
9 J) r' _0 E f2 E2 ~3 j0 L- static void OpenTimerForHc() //打开定时器3 I' m0 `0 P5 g' B. K
- 3 M8 [: @, i2 m4 D( I0 [ Z% `. F/ ~
- {) }# X/ V7 t9 {: M0 h0 x
- 2 ]$ i* i6 m( P' U: I
- TIM_SetCounter(TIM6,0); //清除计数) V8 @4 l- ~1 W, _$ j3 N
6 |6 i- u5 n6 N+ K) j, S* I- msHcCount = 0;
7 w# C0 r3 c1 J
3 z) d9 `: F4 ?* s& C" n* `9 i- TIM_Cmd(TIM6, ENABLE); //使能TIMx外设
2 N- p2 y% s+ Y% ~1 F0 [+ \% I - # ?# x& q+ _4 n, ?* T' {. t
- }# [8 h- ]" Y: G3 Z# r. ^) Q, l
% G( B, q# J' [# n- static void CloseTimerForHc() //关闭定时器
+ I( R6 u) c6 L x1 w3 C& w - 6 r6 x ?# Q( m" U# H
- {
3 O5 r" ~$ B7 k1 O4 b - I3 C5 p! C! Y+ T/ y9 M; E
- TIM_Cmd(TIM6, DISABLE); //使能TIMx外设
: \( \! j1 e% }8 }1 |( r7 L
5 Y. N: V/ W4 O: U- }, W6 z$ t: L! S% R
. l6 j r3 u% D2 l' M9 f- //获取定时器时间
) d4 i7 x! \5 v. G5 B& ]
( \7 t4 j; s. r( y0 D9 O- ^- u32 GetEchoTimer(void)4 l1 B! j3 ~0 Z
" k+ c- H% q3 @. z. L" ~; G% Y- {. _/ [9 [: b0 M( }1 r
- ?( P$ ~# _# ?) x
- u32 t = 0;
9 h9 g* a' n8 G: J7 `$ T! q
% c6 d4 F/ R; E5 A, G, i8 O- t = msHcCount*1000; //将MS转换成US4 v6 k' Q% {, _. B6 J: z
+ k/ G$ j1 M0 I' \" C Z: q% D- t += TIM_GetCounter(TIM6); //得到总的US: W+ u+ B# ~$ ?2 j
- - z1 c- ]( G* _3 @! v8 L
- TIM6->CNT = 0; //将TIM6计数寄存器的计数值清零
8 O7 q( q3 c/ t/ U1 X j3 e
6 @7 k* _# k0 U) n7 E, t- return t;
5 t& k0 Q* v; D( E f - l6 _3 y; ^1 n4 h' y# I0 Z
- }
1 H1 x! `7 L$ f/ S - ! n' P+ m$ D. D) n& w
- //一次获取超声波测距数据 两次测距之间需要相隔一段时间,隔断回响信号
! Y+ a' {$ |$ V4 J
) f% D) s! E. b4 L/ I2 k' p$ I- //为了消除余震的影响,取五次数据的平均值进行加权滤波。9 e$ t" Z+ ^1 b" [$ ^
' L( C0 O9 Z/ M! @+ V0 M- float Hcsr04GetLength(void )
. M! C' ~% J& c* i1 ?0 F# r9 v - + E2 m4 J7 a+ B. I/ }
- {
) Z# x$ g a( O# z) s! Q$ O - / D& v. J) z# Q+ n; V
- u32 t = 0;1 ?: m A* p: l
- 4 l( y- L& G, A+ f6 l
- int i = 0; O# j) L" y0 |& h% q; J
) R; b3 ~+ F7 y; _" |- float lengthTemp = 0;
5 m, D h- e6 ]/ x
% ]" R+ b/ e1 l, d. h- float sum = 0;; B7 U* o3 ]: z8 d
0 Q1 K: C+ F. K2 s* ^9 u" \5 ]- while(i!=5) N. k$ M; v. n% S0 b
& x; ^' x( v/ M0 j- {
. ]* F: X' J8 [9 J. _
8 [. g" }" u7 Q5 B. e# |- /*发送一个20ms的脉冲*/6 Y4 k% W- m% U9 ]* f4 N
- a4 D3 F2 n+ s$ d2 Z' r
- TRIG_Send(1);. l8 K* y6 b7 r& T- ~& K
2 W! d$ j9 I4 S, x- osDelay(20);: P Z- L& g1 p, U
2 N- x/ O- h( n1 `- TRIG_Send(0);" @. L' d) ?& ?# s
- 8 k' G) _+ `! [' C2 Q* P* q5 Y4 A9 ^
- while(ECHO_Reci == 0); //等待接收口高电平输出(超声波发出)# a' h# D4 I) t$ w* s, e
, c9 E4 n7 Y2 I7 ?7 r& i, f' b- OpenTimerForHc(); //打开定时器. x+ h3 y8 `. F% p0 ~
- v* U6 y$ B9 g- n% Z3 Y
- while(ECHO_Reci == 1); //等待超声波返回
3 ~' H: q/ D+ H" t - ' N- p0 M( O- C; S+ Q1 r
- CloseTimerForHc(); //关闭定时器
! q* c) h! F* J3 T: G" X& o* ]/ ?
' ~, t. j" g% x+ Q- t = GetEchoTimer(); //获取时间,分辨率为1US) V1 {" j# S/ i/ x/ i3 X
( D+ s# y# l* q& }% r- lengthTemp = ((float)t*17/1000.0);//cm- K* H8 P- {2 Y e7 O4 c, V1 G
0 N( i# m+ e& @8 i3 {9 Q- sum = lengthTemp + sum ;: `4 A8 V4 v: s: K/ C3 b, [
* `0 I0 Y ?6 J; E- i = i + 1;
2 G3 e. v" R0 ^* n) d2 F
$ N- }4 N W' Q" {3 M- }
7 v* |( w* z( l6 X/ A$ T# s# K - 0 E) _$ c* @: b
- lengthTemp = sum/5.0;4 Z! A- j9 j: {
- 0 {9 b( J% }$ Q+ w
- return lengthTemp;- ?; v( V5 ]4 h& {5 A
- 9 `3 W8 v; d U( a6 d
- }
复制代码
4 [. l) j4 j0 t' ~! I8 H* a4 z8 Y# ?3 j1 Q0 v
|
|