|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
下面是关于stm32驱动超声波模块的一段代码,有需要的朋友可以复制参考,希望对大家能够有所帮助和启发。
+ u0 ?& e3 t+ u. z: Z( ~0 ^ }$ a6 J* P8 \) ~+ D8 p2 s# B- z
" H5 i9 j& O) X& T
. B5 V$ b I1 m2 Z* ?# p) @$ I3 X
, G6 @+ `/ m0 f- F. m, D T, V- #define HCSR04_PORT GPIOB
+ f+ }& i+ _% f+ @
% O: z4 n: G) a% J$ e- #define HCSR04_CLK RCC_APB2Periph_GPIOB
( ~/ D+ \5 Q4 n
2 w0 t/ q% V, X- L, x/ T- #define HCSR04_TRIG GPIO_Pin_80 r8 n- ]. [& X; c+ z% @
- 4 a4 g `, P3 p, l; O7 b3 A. M
- #define HCSR04_ECHO GPIO_Pin_9 ~6 A" H$ Q u" h1 H1 X/ O& T6 R
- 2 B. G0 w. D4 Q. u9 p, c M0 o
- #define TRIG_Send(n) do{ l! U5 `6 D. O3 l; I
( w* a0 U; ~9 x5 A4 D5 z- if(n == 0)
: V% P0 s- t; ~* p. M$ P6 }, L+ ` - . _1 ^% C% w: e7 }: |3 ?
- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);% u7 f& p( N& f; l; ^
- & l5 |8 u8 |, X6 p U* g
- else if(n == 1)
3 c1 Z- X8 T5 [! D6 m& [7 f3 j" M
' H, Q' l1 `0 a2 B5 g- GPIO_SetBits(HCSR04_PORT,HCSR04_TRIG);
% w) J' h0 R! Q, H+ }/ q - " G/ G) P) _' e) [
- }while(0)+ z" r7 _8 r% U1 S
* j# n5 P% X1 z3 a* @# q- #define ECHO_Reci GPIO_ReadInputDataBit(GPIOB,HCSR04_ECHO)
7 p3 b9 e- H1 ]+ ` - / T7 W" f+ f( m1 C
- void UltrasonicInit(void)
: m! w: [+ u( ^( i7 E/ o - 7 _) |6 _5 K! b! e
- {; N2 Y, M$ U8 Y3 O
- + L6 e+ e( I- V \+ U% Y$ ?' `( e
- GPIO_InitTypeDef GPIO_InitStructure;2 {$ {* r G2 v* @0 x
- * E# S' x6 l; g9 p" ?5 N
- RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);9 N; T) u; z5 x5 k
- . B5 `$ `2 c Y
- //IO初始化
' p2 S5 p- [, K% S3 F - . L' r- V+ \4 Z3 x. i
- GPIO_InitStructure.GPIO_Pin = HCSR04_TRIG; //发送电平引脚
# ^6 o) c/ c. O/ l2 `( U
3 q! z5 \& j2 [* d- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;# N& ~9 i6 F) ~
6 K( u0 d0 k/ w, ^- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
2 D0 F; u) H9 N; C: l. S - # O1 @7 ?' A7 A: S
- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
: s7 y6 T0 ~' ?2 \% T - ! [+ D8 n4 x+ `# x/ I6 G
- GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
4 K/ J+ m; O u7 o% C3 w5 a" s f; P - $ o ?1 e. z2 T+ i4 g
- GPIO_InitStructure.GPIO_Pin = HCSR04_ECHO; //返回电平引脚
U5 ?' v/ ?* a& _+ C( e' s( T# a
e* @' i4 N/ M' ], n1 e- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
8 P) r( z( B! w% P - % W% M# S# i4 j( e
- GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
! e+ t b0 F M5 J8 ]/ E) V - ; A p# q/ `( `; B3 Y* z
- GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);6 C6 @, F3 Q. o1 v' s9 C
- 2 G# U& R6 S* \7 n4 l- ~, {, S( c
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //生成用于定时器设置的结构体+ m0 l, b$ X/ r3 Z, i! x! r- U
- . Z0 V2 O* I* @# [" Z
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //使能对应RCC时钟
1 b+ B* y+ |. Y6 }! E; Q
5 b( M3 X& y1 q; n8 P6 U- //配置定时器基础结构体0 X n; F2 c2 ^7 b* i
" C- {& v$ C* ^1 l0 l- TIM_DeInit(TIM6);" m$ g8 _# W( _2 W) U
- " O q: M7 t3 L" Q) R
- TIM_TimeBaseStructure.TIM_Period = (1000-1); //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到1000为1ms3 U0 Q/ b7 Z+ w/ E g3 x9 I2 [
- , w" W; [5 ~# s& g% Y: u' U
- TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //设置用来作为TIMx时钟频率除数的预分频值 1M的计数频率 1US计数
. K; R; Z$ d {+ g* n% I - * v! l+ [3 k9 S0 A- f" F D
- TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//不分频
2 {( `) D w& R1 T4 i2 W0 N& V - 9 L f1 F' _$ m! z
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式1 c% `( f' z( W: K7 r! d9 X( @
- 6 O% h l( |$ Y4 x1 Q- _
- TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
4 X0 G: E! x+ Z: T# {* b - 0 @ N A: e* ^# k
- TIM_CleaRFlag(TIM6, TIM_FLAG_Update); //清除更新中断,免得一打开中断立即产生中断2 {8 `1 t* `( }5 P6 Z
- ^8 b, \$ d, ^5 r0 R- TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); //打开定时器更新中断! P2 ~3 ?- n P, M# J4 S6 \
- , Y- p) B' S5 N0 h6 V: t1 l& K; r O
- NVIC_InitTypeDef NVIC_InitStructure;
, }: D; k2 [4 g- A( d4 Q. E - ) e6 S9 `( ?6 {- ?9 I7 N, J% G. D
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);8 Z, m Q0 U1 t- s |5 Q
( c* _# P/ y$ X0 o3 |- NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; //选择串口1中断2 H! B0 y& P% y! G
- - l/ Q- {6 N5 e, X
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式中断优先级设置为1
, r. K& h7 A1 Q2 v, G/ {2 c
/ \: Q& X+ i* Q% N1 g& i8 B- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应式中断优先级设置为1
+ ?2 U0 V! k2 l( r# e6 R) T
4 m9 ?8 U5 j0 [# |$ i+ u- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断, C1 U6 K- w) O: U" z
- ! c& b V- b; d
- NVIC_Init(&NVIC_InitStructure);
5 M6 I& D$ B- w7 l/ A) v - 7 z0 ?+ u, I- G+ n
- TIM_Cmd(TIM6,DISABLE);0 L8 d: |4 L4 w$ h, x* i
- & @- } d% v8 |0 g
- }
! s4 B* ]* i& u) F' k1 X+ } - % k! m" ^" M5 H4 e! T2 Q. x
- //定时器6中断服务程序
C) L6 C* |; O( x9 a7 u y0 Y' m7 Q - 3 v+ x1 Y& ~7 W4 g
- u32 msHcCount = 0;$ V L4 ^" w9 {2 f* g# G
, j7 E2 L& C" [! F/ V. v- void TIM6_IRQHandler(void) //TIM6中断: {) b1 j0 s5 s9 O) p. E; b/ {
C/ y+ V& r5 m7 V" _& d( e- {
% S/ z" E3 L+ K" E, ]1 C
7 v6 T [; D1 F# H5 S- if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
" e2 j! ]$ ]( t1 Y6 m6 P. S - ) b) ] ?1 P0 R0 u3 H! v
- {
; s1 Y9 a! E1 K. ` - : T$ w) g" {0 @
- TIM_ClearITPendingBit(TIM6, TIM_IT_Update); //清除TIMx更新中断标志; _0 q& X1 |# Z7 f
- / G3 T- K' t+ `
- msHcCount++;
, R7 Y' \" p/ i% j0 R - " j2 d6 ^' ?9 x& r6 b% o/ w) c# h6 v
- }
, j1 B# {$ I: {9 v" ?' `
" J4 a4 s- g! v" z, w& t( ]- }0 u z- R! ?: T q3 z) w3 O1 g
4 v9 \8 _, o! d# ^8 c- static void OpenTimerForHc() //打开定时器
5 f! x; O- G5 J$ r$ c1 C" D
: T* D% o% f/ |- l, n/ z- { n. L$ o. g# R, H% p
- ( p" m& O2 c& R0 O
- TIM_SetCounter(TIM6,0); //清除计数7 ~+ \" t. A, [7 M( p! z
$ ?" M# P' [+ R* S5 T. l2 {- V- msHcCount = 0;
# H2 g8 T. c: k# A7 N4 T: i2 G - + H4 i( |1 Q* G0 F4 L* p3 w! [# k
- TIM_Cmd(TIM6, ENABLE); //使能TIMx外设
! R' a6 m6 S2 U9 ] - 7 ^- l3 {( Z: I- o+ i& a0 O, a
- }$ W I& n; D6 }: h
- 6 [% p6 C4 Y5 n4 m* X- u
- static void CloseTimerForHc() //关闭定时器
% j) S% R, q T0 A- c2 M$ v - ( l# e/ C( D& W1 h( N) S' i) Q
- {
. h/ I. R" u7 N0 `! v
4 n( M7 ^- F9 u0 Q, k- TIM_Cmd(TIM6, DISABLE); //使能TIMx外设
# ^& Z9 y5 ?4 k' O1 I$ R8 E" `
( }* o1 l# e* c* `, L K5 D- }6 v+ c, G( |$ T9 {- W3 h8 `
! S! K2 H+ ~3 \$ k& G" d; `3 H- H: ?4 i- //获取定时器时间+ {1 ~+ [; x* G
- # d: o% F8 B) w+ `
- u32 GetEchoTimer(void)
7 t1 x( o& {2 l' l
1 R5 E- ~& s; M0 o, H1 E- {8 |6 Q0 u8 V0 S
- 6 @4 s, ~, `) A) L9 N1 y9 m
- u32 t = 0;0 u* s( Y: }# K* ~- h4 }8 A
4 b& i6 h, [/ _. l- t = msHcCount*1000; //将MS转换成US( { p! D% Z. d3 r r1 v
f. C) ~6 L# {$ Y* P- q- t += TIM_GetCounter(TIM6); //得到总的US- R7 H9 G: T/ Z# L R) `) r( c
- , N5 U7 n5 l, H" I) Q9 z
- TIM6->CNT = 0; //将TIM6计数寄存器的计数值清零
; R! \7 U. o% x9 ]* o8 \$ O' K
8 c- F* M2 n. k7 A# L& |9 M- return t;/ @' k0 }) q% @+ R% }. B2 R2 [5 S
# t8 o; E* [& Y8 D6 k% r1 [5 r- }3 h9 G. m, l( N
; m6 S( v5 x! X! @% ^- //一次获取超声波测距数据 两次测距之间需要相隔一段时间,隔断回响信号
7 J. ]0 T5 m. }- @) d; ~ - " ?4 e6 \7 T0 \$ A% E
- //为了消除余震的影响,取五次数据的平均值进行加权滤波。) W. ?9 z" e$ e. i1 T. F
- 8 n+ C0 N* e7 {! E
- float Hcsr04GetLength(void )' ?8 E _& u0 J1 ]' l$ x
- * I( j- n ~ _& c% D* E
- {% ]7 w% @ b9 H) V) e
- + K/ ^$ W: L4 @+ s4 G
- u32 t = 0;9 S& I4 R- y% ?6 U) T5 q% j
' ]* F) R T$ z- int i = 0;
7 `: l# a$ Q0 N1 m$ ^* D - " r; O, C4 h7 _) M+ |3 m" s9 Y
- float lengthTemp = 0;9 X3 B9 A# [8 m( y, w. M( u: S/ Z
, G I5 y# X: _- float sum = 0;
4 B- i, ?0 ~0 Q9 @7 X% |
& l/ z$ g2 K* z8 Z# t5 `- while(i!=5)
/ K1 N6 Q, T1 y+ ?/ N' T
" F1 H1 F1 l. W7 U0 f- {
" y* b( e3 j- z5 g9 y }$ ?8 C% m - 8 v( s8 Z7 E7 f: U) B/ S
- /*发送一个20ms的脉冲*/
* G. f8 v/ z. \9 H
# Q3 `# x7 }5 r( m' |* w- TRIG_Send(1);: f1 R6 q7 e3 f/ A- I, u
/ J( _+ l: i* C1 O- osDelay(20);# N: ?: ~2 w X- ]
- & q0 `7 k# W; Q, p) I% u
- TRIG_Send(0);
- l* D+ ]" N1 j4 C( ~7 Y - 9 j0 T7 ?/ e/ l7 k4 Q
- while(ECHO_Reci == 0); //等待接收口高电平输出(超声波发出)( B! b* Z+ p5 }$ e0 r6 X
- 6 A6 c8 u9 e9 | [' d
- OpenTimerForHc(); //打开定时器
# @. W& ]- p7 L: s7 O
' @( H7 `* _+ \' U O- while(ECHO_Reci == 1); //等待超声波返回
/ v" W4 I7 k" v, e5 }8 U2 W9 z - . i! y: W& P# ?; g
- CloseTimerForHc(); //关闭定时器6 G5 c5 i2 e0 Q6 i3 o7 r
- 5 f+ v/ U" E% s; h+ {7 y
- t = GetEchoTimer(); //获取时间,分辨率为1US* F6 S# o3 U2 L
- + B7 @+ {+ O5 n0 e5 |. N4 L% S' @
- lengthTemp = ((float)t*17/1000.0);//cm
& A2 i! R2 ^- H - ( A9 Z% r6 n% u/ v) U
- sum = lengthTemp + sum ;
0 e& T V2 N1 |# D
( j' Z' C7 U* p5 h& `3 y- i = i + 1;
; h' ]! Z) |) ]; ^, l/ H [
: w6 D; i1 l7 Q% s9 Z# k/ q$ j- }! B- y' N2 i- v) g" z4 l( h
5 X( N; C7 [# q! L6 W d- lengthTemp = sum/5.0;% \: S1 S, r4 e8 {9 w; C S
7 O9 h- z& x, _) T3 J8 n- return lengthTemp;$ A# C9 n4 c+ Z3 i' |
- 0 y+ V0 B; \/ Z6 i2 t3 M9 u3 r
- }
复制代码
$ I0 U$ ?3 F4 x+ Z& M: g) N8 C3 ^; L: K
* |4 k: T4 q8 `& k3 ~: G8 D+ _ |
|