|
【年中粉丝节】+超声波距离传感器 今天分享下板子上比较大的传感器,就是超声波距离传感器。使用超声波距离传感器就比较简单了。 首先看下超声波测距传感器的原理,一端发射声波,当声波被物体阻挡就会反射回来。被接收端收到,只要我们算好这中间的时间差,加上声音传播速度就能算出距离,有如下公式: 原理图是这样的比较负责了,用了一个555定时器产生38Khz的方波,接收端其实是使用了一个CX20106A的红外解码芯片,其实这样是频率对上了,之后是为了程序方便,初始化一个定时器中断,每10US中断一次,然后把接收端也放一个中断,这样,开始发射时计数清空,然后定时器中断计数,这样来算时间,之后通过IO中断,来判断接收到了。在根据上面公式就能算出距离了。 - void Ultrasonic_Port()
@% v! A; `7 E/ r- n% T* l
! u9 z6 m& e8 k j5 q" e- {' [. w- o0 [3 @ @* f3 o
6 {) I( i' O2 Q- t R/ `3 @3 K- ) Q6 Y) z( u* D0 k, y" j
J8 V2 S4 X! Y: e- GPIO_InitTypeDef GPIO_InitStructure;6 j0 ?# M8 Q, P" q
' V' U* r3 U0 j G o; H$ G-
: y$ A$ i" @- M
$ ^! q$ j& |+ R7 z2 P( G- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);- X- p8 F7 D9 z0 T7 ?& ^$ A
- ) V3 t! u: \8 x+ n$ E
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
* s+ l/ A2 Y+ f9 E, }1 W - $ [, v$ ^1 n4 S8 W% h
- //改变指定管脚的映射 GPIO_Remap_SWJ_JTAGDisable JTAG-DP 失能 + SW-DP使能 K9 y Y9 h1 l, m& o3 g
- , v# }. {6 j+ f" p, A
- GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
8 h6 G$ }# {9 N) |' L5 ?5 u$ T - ! S6 O+ S) k* S2 b! t1 A7 u1 A4 \5 @: Z
- X" n- W. Y" O4 ]; O( _# D( f
- ; T) W. ]8 L+ p$ m( p$ D
- //PB6-SCL PC2-ADDR
6 S& p% B+ y4 l' u
* v0 t9 K+ B& H1 ]6 Y- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //PA15
; j- ^& _9 |4 c" j$ {$ K" S, Z - 0 A' J, P+ V1 D! ]' D2 K9 g
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;& D/ }" s, b9 s: }* _
- % m( d/ y% e* G$ K, d
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //复用推挽输出
" O* a8 n1 i* A5 ?' A3 m
6 S& i/ E7 U q5 M* t# G; t( u0 V* c- GPIO_Init(GPIOA, &GPIO_InitStructure);2 P8 Z; a) k' n* R
) M" T6 S* l8 t- C6 k-
# p# ^; V# e6 m7 _; q9 l2 R
) d( r( ?' w7 L y+ @0 p7 ?6 ?- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;. G- l$ Z) r/ [( o" ] V
- $ d7 y2 E- T) \8 T
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
! p" B- q" d* o {1 s - 3 k! A. A) f, U- w2 I( o" J
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
$ a7 ]! [3 \7 {( S) a) e
8 t( R7 l; c& p% f" J7 n- GPIO_Init(GPIOB,&GPIO_InitStructure);
% B/ _2 m1 S% K: m - 4 T9 L; N& R* a: ?* u
- }6 A3 ]! m2 Z% L- I' m
- ; ?/ d( H% r; B- r( _; F
-
4 |( V* }8 n* ?" }
; z3 N8 l$ b7 J' ], O" G9 Z5 u-
# ^8 P! ?0 E4 f7 K - ; t/ _6 o8 J' \" o" v. K
- void Ultrasonic_TIM(uint16_t arr,uint16_t psc)
! w S* l n s6 D& j
) ?& _$ i' ?* [+ U5 R- {
( i$ n$ a" Y/ [. L, q J2 P) N; ?
/ R( C# p/ a) f-
* i7 f, j$ _' E+ g1 |; p
4 ]. A ~! E% f7 g- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
: t0 M9 _( a. ~& S: \& z
2 ~- {; c' n( G5 @2 x- NVIC_InitTypeDef NVIC_InitStructure;9 \7 x {5 ~: O$ }7 |
- 7 C0 w/ S& C* p1 t, b) B, M
-
2 D% O0 Z* L J& p
/ p. g! _1 B/ A. u- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能) t4 `& B+ m6 n& q# j
# d0 Q* M+ V7 V-
X/ m" F1 [7 |% ?, Q) R - 5 C# [/ C" E$ Z, z1 D4 t
- //定时器TIM3初始化
! H/ J/ a7 J6 J5 a - , |- L0 ~: M2 i- [
- TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值- M0 C9 g# ?; K5 A2 m0 v- N3 f3 h% j
! O0 T2 B" U" U. l) T5 j) e- TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
- _9 S2 W, f1 l% v$ f: T - + S [5 i. l4 ?+ d/ T) W, ` V
- //TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
2 i8 \) s0 r+ j; ~% l- A7 V8 X
/ J# R+ ~/ G: i6 A- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式+ ?# }( N5 K/ c, w/ s7 ]7 ~+ D
- ! o9 g% C$ G8 y% k$ r6 |8 R J
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
4 V8 O; e% [% p+ d/ L - " r; Y0 u$ T* V5 `* l
-
# R( a# e6 _' Y- @9 T$ P8 n
) O, I3 x" A3 q( t- //中断优先级NVIC设置8 Q/ I, U, h* }/ O+ E
, f* P ^ m g9 m7 i0 {- NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
( w- B! g# q+ f( r5 y
1 L0 f- r7 T% _7 U8 Z- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
2 a* T/ u) q, j2 t* S! H( l - . q: A" I+ I% l% p6 z
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 8; //从优先级3级- w6 m8 g, Y* `. ^2 A& Q
1 u/ ]) R$ X! V# A& S0 E: P- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
3 H$ \, B3 n9 s2 \. Z& X
6 j4 G6 p5 {; f$ f- NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器: f0 ~0 E: s+ n) a& y( c
& ?1 A. @/ D- c$ d6 ?( d0 f- 8 h9 M+ E: n/ O' [
9 a* V! M$ @& w- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断& }; [2 ` m- D O
- ; o2 B$ Z: [; u- |
- TIM_Cmd(TIM3, DISABLE); //使能TIMx
8 ~# Y3 E. [0 j0 M$ I
: J) W/ U5 v# E( {2 `; b$ K9 w1 `- }& P" G, \# S' a' n/ I
" Z6 W5 Q6 s0 _% v7 z-
8 ]9 G$ [" r- q: u0 g) A& q. X5 s - $ `9 {& d ]' L8 F& {
- void Ultrasonic_EXTI()
) n. [: x' @3 h! F) T! L2 C; _' A - : F+ n. y. E0 B5 ]# U3 C
- {
, u! L( g; A% {$ F" G' i( }3 Q% ? - 3 Z! p9 B) G2 d3 o
- EXTI_InitTypeDef EXTI_InitStructure;
$ x. T/ |$ \( d+ }. m
6 N+ M% t# w m4 a: N- NVIC_InitTypeDef NVIC_InitStructure;' z, W5 X6 \) ~7 P: m7 L
- : a; m. X8 I0 f a1 m- [
- : b' I3 t. L' z/ ~9 u: `
- * M8 G$ u# n, p- [$ z* _& F- ~
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
) x8 j% P: z+ c0 g! r1 r
$ A, I# Z, X7 h) Q/ I4 w-
; `* u. r- T0 i- m1 M
8 V8 R( r: J% O7 b8 d5 B- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟
- W t2 I9 r$ E" b& c- `/ L
+ d6 _1 u) P0 i! w7 A-
) V& N% A& o) F5 s) v" t/ D - 9 A: _ O; m. [2 g1 d+ w
- //GPIOE.2 中断线以及中断初始化配置 下降沿触发
6 x7 h* Z2 A- M1 t1 i/ B
% |5 |" A" h+ k( F' E- L2 X9 ~/ z- GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource8);$ b* V) _3 T9 |2 @7 l
- 1 s$ t# _* I; {. i
- + e: w# P( g: S0 m, ]
- 6 l9 e' g; u9 m' N' U* Z
- EXTI_InitStructure.EXTI_Line=EXTI_Line8; //KEY2( o4 d E/ O- X6 \' t$ e
- 3 n& J& h2 t w0 Q
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 7 x- G5 O- v, N$ `$ ~
D- O& ~6 O/ D/ D1 M( Y1 k- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
7 k, T- I& v, T: b% F: {; h3 | - * A K* `5 t- x$ Y
- EXTI_InitStructure.EXTI_LineCmd = ENABLE;5 B* }) v Q) O3 `+ ~# z |3 ^
- ! V d9 ?5 f* R$ ]+ M U8 y
- EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
L2 |. N7 y C8 p- F - ' O/ O' |# l& h+ A; \
- ( z3 ?* y# z, J- } M$ Q
- 2 A0 B3 o8 ^2 L
- NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按键KEY2所在的外部中断通道% G6 G7 \& l7 C$ ~/ \; |
- 4 {# u- X! c$ V9 E, v
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级2,
2 I7 }5 K. }* n, i1 i' K
. z. ^6 ?# c7 ^+ k8 E& d3 r- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7; //子优先级2/ \, k* O' f; Z0 U1 m
5 x: D) k. V! U9 M$ c- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
) n k# E3 i' _+ D" |% @7 I" M7 I( }* X
( \* b# W, }# u8 a: j# }8 v- NVIC_Init(&NVIC_InitStructure);7 y0 _* L* O; F' t3 g- I
" T7 ] s( n. Z4 M-
% U L6 @( I p% j2 m0 L) l5 w4 e; x
5 O8 @+ ~& L4 {& X0 N- }. w3 [; g2 G. T3 O* G7 ~. {. O% o
' p3 M! e g& k9 R2 H: j" @- # c; Z2 @1 ?, L" x# X/ L
/ X8 I1 ] x' {- i) j; I- void Ultrasonic_Init(): h3 p' f# P1 h$ m
- 7 B4 N8 w) \4 b6 F8 I; |) I
- {
C4 @8 w" E' b. o
' `! {, }/ G4 @. y5 F' @- Ultrasonic_Port();
. u& Q) }; ~0 h" I! y+ {. h - ! |! g# U0 h4 J% V) V
- Ultrasonic_TIM(9,71);//10us0 @ y# Z0 z2 a% u% _
- 8 r- _' R( b- Q9 X9 C# A7 Z4 |
- Ultrasonic_EXTI(); u# u$ `3 A9 a6 V- \1 j0 Q9 e
- 3 F0 ~- g3 m A- y0 R& D( g5 V
- }
+ t; I/ @# `. b& g1 G) H4 n - & h6 N0 Q5 p* f5 s
-
& f: w, {% M) X& A# u' |" [ - # l7 ?% ^" S8 P" N0 j
- - `+ }. a$ o, t$ s: ]6 C( ~+ r
- 3 _3 p) [: ?* C4 z
- //超声波测距! f" a0 N7 s) l: ^* T
- 8 ^6 @5 `0 Y c' Y. I S& m n
- void Ultrasonic_Ranging()
0 b) ]" [2 r' D - # K& N6 n# X: d V0 `
- {' x5 f; N9 x/ _
' E# |1 ~. R' G1 l- INC = 1; //关发射 8 _4 O1 g7 I6 b9 X( F: n
- 7 H1 ^6 ]# d- V8 q
- delay_us(3);
8 [! A6 p; B6 Z+ Q O" q' O% ]
1 k. e" B! z8 D$ f$ x$ w- INC = 0;
1 o$ X; E- ^2 a5 X* [5 E0 y, M* { - ! s' S- a2 J q4 T e( B
-
: ^: b) J. K/ `3 Y8 o) d7 y - & W4 l2 t$ U2 {) p
- TIM_Cmd(TIM3,ENABLE);
* H' ^, G4 |5 A. w
! T: a/ g! s5 S; W- C$ ?1 u/ @- //EXTI_ClearITPendingBit(EXTI_Line4);
0 ^2 ~, X; |. Y8 ]
! T% o5 @5 Z. n3 _- TIM_ClearITPendingBit(TIM3,TIM_IT_Update);8 j4 P) M$ p8 @. ^
- : L2 l" U6 Z. ?3 {7 R. o+ D( i- m
- ; J* g( c6 W# w9 ^& |
- ' e) m8 G! M$ H! _
- Ultrasonic_Num = 0; // 定时器清零
* z0 B) |3 p! g# w: j
7 o" Q( y5 V; H/ x6 e: ?-
- F/ S- _3 l3 h7 M/ N. `$ Z; }
3 Q# z" K3 L. I% D8 U3 o' j) f& R- delay_ms(30); //等待一段时间,等待发送超声波控制信号
, ~+ h5 o) `/ O - 9 T& y* U6 Z# z- y
- INC = 1;. Z; |( b% U6 \ i: g
1 |# k6 O7 U7 R# L3 c- delay_ms(5);' i% _1 J; Q; m' z: Z9 Y$ n
! \2 T3 ]9 g8 e0 Z! ~7 X- }4 y( [ o7 ]) P4 J" X" ?
A" w3 Z! Y4 _( n-
& I! U2 V+ [* m3 {
% h% r0 l# d7 Y- //定时器3中断服务程序
b9 m y) F- o$ J+ ^ - 2 y3 i% e3 ]9 e( Z& y% s
- void TIM3_IRQHandler(void) //TIM3中断( Q u3 P9 R8 e/ d
- 7 ~' u) R+ t; |5 {: W$ x; @6 G6 d# p B
- {+ V* K; o7 z5 e3 U9 l! Q1 G: ], B
, C& Z5 ~9 {; l! o5 N C1 `- if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) //检查TIM3更新中断发生与否' W$ O' h7 w9 v, m, H i& j. J$ |
/ X4 `& V3 t3 T x- {
4 n5 j! z/ O b- p/ e+ T! F - % ^% `. O. d' n! H& t
- Ultrasonic_Num++;$ @ c6 F9 C7 k% G
( f6 t9 N( b1 W+ ^! P- }
( \6 s% n1 Y" U; v) e - / T9 Z+ [8 p& g; z; ~) T
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx更新中断标志6 g6 \6 j; ]* s j
5 T) T G- h, f ?- }
( a" Y$ g8 {& b- ]% p
) e1 E8 `6 z. o6 v/ M. E- - L( W$ {+ n. U M0 A
- 5 C! w4 d0 d8 V& I. Y5 T) c! Y
- //外部中断2服务程序
! R( p3 U6 s- J5 P4 d/ K - / P4 R* Z% P5 L$ k, ]/ I2 \5 g
- void EXTI9_5_IRQHandler(void)
* V! E% C6 X# ]2 V - , S( M1 x5 d5 R0 \
- {0 X% _+ r1 Y. I7 M5 F8 X" E# f
7 Y* d: R2 o: g4 U# |) C- if(EXTI_GetITStatus(EXTI_Line8) == SET)
, q! b# K4 z2 o/ ~
1 N6 A' f' z ~1 l8 L# {4 q+ P- {1 S: m! q: v- p8 i* H( C
- ! F- a1 @6 }: z0 H6 v$ c
- if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8) == RESET)9 `% |6 ]5 y) n+ ^
- 6 ]4 R# N5 R; H e+ N4 V
- { & x$ D6 k( t1 ] l! R
- 6 U- J# d7 x* n/ M' M" T
- TIM_Cmd(TIM3,DISABLE);
/ ?; ^" ~7 N4 G
) m7 l* N3 H+ Y8 g$ ^, o- Ultrasonic_Value = Ultrasonic_Num;
+ G- {* u$ O3 [7 S/ t - 4 [& ^9 M7 q" l4 i ~9 z; A
- Ultrasonic_Value =(float)Ultrasonic_Value*1.73; // 计算距离定时10us,S=Vt/2(减2是误差补尝)! {! T0 H( v* ^1 a+ c/ f3 Z/ a. y
$ X. G; ]+ F9 q% s& m* ]5 J5 A- dis = (uint16_t)Ultrasonic_Value;, I5 X# U J. ~5 P9 s2 u+ b2 ?
- 6 {& i6 H, Y- U6 C' S7 W
- }0 s+ a: V) R Z* o$ x4 |2 p
- ) d' V# R9 h! ?# B
- EXTI_ClearITPendingBit(EXTI_Line8);
6 K( O6 i0 f7 R9 s2 q
) ^: X @0 j# s4 _! u. `1 R1 B. n- } 5 j3 `( D0 l! B2 D1 K
; U6 ^& W1 Y, c' s2 M+ i- }
复制代码
7 [! c7 D! b! C 实际测算还是会有点误差的。 + Q. @- |3 v% U2 S! t. K( O
|