|
【年中粉丝节】+超声波距离传感器 今天分享下板子上比较大的传感器,就是超声波距离传感器。使用超声波距离传感器就比较简单了。 首先看下超声波测距传感器的原理,一端发射声波,当声波被物体阻挡就会反射回来。被接收端收到,只要我们算好这中间的时间差,加上声音传播速度就能算出距离,有如下公式: 原理图是这样的比较负责了,用了一个555定时器产生38Khz的方波,接收端其实是使用了一个CX20106A的红外解码芯片,其实这样是频率对上了,之后是为了程序方便,初始化一个定时器中断,每10US中断一次,然后把接收端也放一个中断,这样,开始发射时计数清空,然后定时器中断计数,这样来算时间,之后通过IO中断,来判断接收到了。在根据上面公式就能算出距离了。 - void Ultrasonic_Port()* I! ?3 I: T {5 z- N4 Z) b! i0 P
& ^1 Z5 a7 q* {3 H- b- {5 h$ n8 T/ L" p2 ?' d. Z
& o& a# i Q; u8 ^2 s4 ]$ G-
0 Y1 p3 z8 i& v3 K& H. V! N - 3 z+ n8 ]( v: b. c5 ?, ]- e2 p. U
- GPIO_InitTypeDef GPIO_InitStructure;9 ~! k, ]1 a Y) U, A+ y
4 z ?8 K! H* b8 G+ N7 N: R% K- _% k/ ~- 6 @4 o1 X o7 C& T5 {- i ~2 W
- 1 {! k( {4 M) U7 Z0 t6 c1 T- l! {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);2 a g7 w- q% {. B' \: }
; A2 ]5 G+ I! U- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
1 s5 X, w6 v4 E5 }4 _9 |
& J0 p% k' n, ~2 o: I8 Y$ s- //改变指定管脚的映射 GPIO_Remap_SWJ_JTAGDisable JTAG-DP 失能 + SW-DP使能) ? { T; S L
- ; {6 F, }" ~- f
- GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
! G- T; n' N9 @1 @1 O i
- U$ \5 B$ L' l# {) \ H- $ L* M" n$ z* ^
- . ?5 b* s2 G6 w! T6 b
- //PB6-SCL PC2-ADDR
/ L- |7 m/ E/ T7 K9 ]& Z) u4 a" O - / _6 X i, I% U' {% k0 F- V
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //PA15
! D" p9 {5 q9 j) w5 ]* R
7 \1 A; b! p0 T1 `- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;2 g1 K. c7 ?2 y6 d
* v5 M4 Y: A- c7 K, q2 `- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //复用推挽输出
) [# v8 ]6 W1 d8 Y" K - 3 X; E ~3 ]7 X. M7 G& g. U
- GPIO_Init(GPIOA, &GPIO_InitStructure);
a# }. c+ S/ A- w4 L. G; |. |- }( n
* s8 e; x: F; z9 Z+ ~-
6 v% i ]; @8 s
/ {1 Z6 _- I; J2 T5 |' t- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
# U" \; d; |: ] - / }# g& r' k) f4 M$ x
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;; b% p& p F% Z% S9 j: U$ D
- # p, m# i+ i2 E
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- }- g8 X ]' \5 Q. l3 v4 q# A - ) p4 \9 W+ A; r3 L0 {% i2 v
- GPIO_Init(GPIOB,&GPIO_InitStructure);
+ G) K0 d: z6 G
( O6 q, c$ t( [; X' H- }
% } G) |& E3 S - ' c/ B8 r9 Z% [
- 5 w* s& V% m$ b0 B0 i
5 d+ y( R% N/ [3 K- ( [# w" B7 F' ~, N
4 m. k! k- A4 k5 z+ ~- void Ultrasonic_TIM(uint16_t arr,uint16_t psc)
; b4 ~3 O; j+ q6 r - 7 A! }, `: H6 s$ P; T: C! o
- {7 V7 n5 D; m: d2 H2 T3 t, t4 K1 [
0 Y9 ~# i! r" n% O* y( s. |-
' K) R: k9 {3 n) X+ O3 E5 ] - 7 u& Y# e& U; d$ v; G+ x
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;: ^7 p3 B; Q0 f1 S) [7 x
4 v% q. g& ]. s- x; F3 d5 E- NVIC_InitTypeDef NVIC_InitStructure;8 y$ C- x3 Q) ^7 I0 x
- 2 ]6 V4 I! J$ l, G
-
8 h' U: D+ q* D2 Q. {' _& f - / V: n7 w! a1 g) M9 I
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
; q) O! A) h" C - # h/ S5 m/ ~/ d# ]
- $ M4 k: O# b4 j! N3 a. V
- ' l: c; _$ t0 N/ t- N* Z: Y$ f: w) N( u
- //定时器TIM3初始化
& X+ b0 g8 E9 O- X" C' x- i' y
! y% h- [5 E2 w; T- TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
' c4 N2 G* H/ `/ i - ) f6 S' u. p* X" N# B
- TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值/ w( g0 Z2 \9 c7 D* G: H5 @
- # F m& U6 w: Z1 ?) _1 O
- //TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim, s5 c+ ]# C1 f+ P
& }+ s6 f% P# z ^& d7 F; T- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式3 b8 A p3 ~* F3 c& |$ B% j
- + U& j, p0 z. u+ o1 U8 _
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位! q- C5 X6 ~* B3 X
- 6 D5 q7 I2 }' U5 A4 k
- 9 W2 E6 N ]5 d4 S6 T
- / \, ~9 k* e. d t" L
- //中断优先级NVIC设置4 M& i+ M+ g$ `5 \
- ! B& h9 g( _: p8 A
- NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
% [$ r) n. e) F# \. a - + o+ q# {* I+ W* T6 x4 ?( g
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
4 b3 w+ O$ W# Z$ R - 6 G& C& u+ A6 N/ Y
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 8; //从优先级3级0 {7 n6 Q7 E: O* i' j; ?: R
- ! r; i& B& [/ d3 g
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
# p( H* U2 H0 p# u5 O5 u
5 j; v) S9 b9 n# v9 N3 z# f% {- NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器& ~& a0 S5 F, O) t* L# V0 W
( y8 t* q# d/ @6 c-
x8 R( z2 a& e4 W6 i - , a# b" ?+ M& r4 n# W+ F
- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
: w1 d2 e: l/ U# v( S' U; L# D6 I" k
0 M2 B/ `$ O0 B8 i: m- TIM_Cmd(TIM3, DISABLE); //使能TIMx $ }2 |7 h+ O* g8 R7 o- @
- & ?& @+ _# z: o7 K
- }
& L, f1 E; E8 W( n5 i - 1 Z2 M& H! z/ ]# H, U
-
2 b; V( r( n6 e, G5 G! V
& x( T3 P \2 X, e6 g/ @# W1 X6 m. U- void Ultrasonic_EXTI()
) i' |7 C4 Q! A! f" m/ l
) o, U2 c/ _% J! z- {" {6 J( B' P3 b
0 Z: n" c" D* q8 @% J8 S9 h- EXTI_InitTypeDef EXTI_InitStructure;& ~) f3 E. F* @! u
- 5 Q& d [& u9 ^6 n
- NVIC_InitTypeDef NVIC_InitStructure;
2 O* D5 A8 U6 | F1 @. m - ) S% J6 B" E* _; S
-
( \ q4 c% N+ o* m; U: i - & ~4 R! w& O) u4 R+ |
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);6 N3 ~/ n3 \& Y
- ) R, v4 d: r- |4 H4 I
-
& {$ ]% D+ r, Q$ \3 Q - , W+ }2 |! I$ k0 }* `: B1 C* s
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟
/ Y% @* [ _* A4 ~; Y# D - " M/ |( J# I5 h; x/ A
-
+ z! I" N2 F" y& t
/ Q: B: J0 K+ _% D% f* S- //GPIOE.2 中断线以及中断初始化配置 下降沿触发
0 v: I& O3 ]( P5 ]) G3 f# [8 u
1 [ L F5 f3 a6 f0 B/ l- GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource8);
; G3 D: z3 _8 W! X! h
8 f/ |" T' E! x) z9 C-
% ]* r7 x3 O% Y* ^4 a) @0 ] p
! R) s* V3 P3 a. K! S% z7 U- EXTI_InitStructure.EXTI_Line=EXTI_Line8; //KEY2
+ W# y, x) ^/ u/ {. k - / {' x- j/ _! ?3 `
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
& w1 }6 c- ]( O% Y% `/ a
- T* S9 M6 m! r- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
8 E* j+ L+ G: |8 k
/ S' e5 x# S. Q0 a- EXTI_InitStructure.EXTI_LineCmd = ENABLE;
2 Y! m# |- c* a. \4 p- o) d; J - ! c2 q9 K9 i5 u, z( l
- EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
! D" ~# q v# P: H: ^- \
, V4 h9 L* Y: F1 `" O# w-
! G' G5 _6 `4 K. t6 \' x - 5 s! p1 y- }: k1 l4 V: I, }
- NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按键KEY2所在的外部中断通道
" t( l/ { I2 H5 A9 B
. E3 n, l# ~: E/ f: M- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级2,7 L9 J" I; o! C. x; s2 Z; b* Z' Z
. \, p5 I; e8 ]' z9 W3 I& p2 F- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7; //子优先级2, [, Z3 ^( [- D- O# P
- / _* c; H/ z# N4 B
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道/ n! U* S: e: C: j: ]( e
1 g+ x& \) T. M1 B- `- NVIC_Init(&NVIC_InitStructure);
5 D, @6 y$ n* g* b# w9 N - 3 l" y' ~; X* _0 G( E' @- Q4 w
- 4 @, O1 K% G8 c0 R
8 j2 w# J7 M! l' L& V- }% [/ h0 t# s" x
- 1 V9 J1 ]* t+ V
-
0 E8 y7 u8 B" g D2 x) W
1 p# E7 {$ c, n2 Q- void Ultrasonic_Init()' n' o+ n4 `" o1 H6 q) c( f
% a$ }! ~4 @) L% s$ O" h- {
2 C2 n: w T8 b. K6 ~ - ' N% D4 r: v$ U6 B7 ^$ v% J
- Ultrasonic_Port();# h% Y: g1 Y( e5 U9 i
( V3 j. Q8 T% m( b8 j: _- Ultrasonic_TIM(9,71);//10us
7 f, g/ t9 x* d- f& ^6 b( A - ) E2 }) w1 h# [
- Ultrasonic_EXTI();
: j" X3 E& S9 V1 r. p8 \ - 7 }. A' w- j! b' e9 L
- }
3 S; Z' A' v5 h f, o+ R
3 y# \$ U9 m) l( Z1 U% K-
& k- Q! a4 j4 X& M - X# X) n; u1 K" G/ l9 o$ o
- # j) ]' i+ `4 `% i
$ J% h$ F% I. G" g- //超声波测距. @3 ?# B7 ^( R8 x A6 X7 `+ b- i
# {# F; Q- r' ~+ {# X O, {- void Ultrasonic_Ranging()
! y* q* y2 o2 Q" \' Z0 d0 o - * f) R* U- v o) i5 v
- {' i7 Z/ m5 c0 B( y7 }( L: q
- 3 o- u) m- [! k# g
- INC = 1; //关发射 & V* K% |. d2 E. z4 T4 N) H7 a
- : a8 u5 B4 t3 h; O6 @
- delay_us(3);
* Q: [7 o) e1 U% X4 l0 A/ A; m
; _% s |/ l7 \- INC = 0;% [# h5 C0 r4 }: D9 O
- " W. g2 E+ [ q
-
7 m _) g8 u& {. H# }6 j8 o
' Y7 m2 M- Y; q# _) }1 r9 S- TIM_Cmd(TIM3,ENABLE);( `+ b c' d3 e1 f
- $ Y2 D1 ]9 l5 o5 x( g6 s$ q
- //EXTI_ClearITPendingBit(EXTI_Line4);6 `7 K @% B, i
- + L* e. Z& z7 T u
- TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
2 Z& S M( d( R2 a - , o$ i# ~$ N7 b4 a J8 S: N# D
- 6 \1 x( s$ D0 i/ K/ i( c4 e
- 2 b( T. g: b' y
- Ultrasonic_Num = 0; // 定时器清零
) Z8 u) X$ t3 o& q: h7 u
; F, F7 d. ?# d$ J( W+ f- % \* a5 Q( \- w) S, p
- k' P7 e' E# c$ m( E/ Z2 `- delay_ms(30); //等待一段时间,等待发送超声波控制信号% N9 ^- d) J( E8 D- ^7 e6 w8 H; Q
- 7 f; H# k0 K" Q' }2 y J, G' g- u/ ~
- INC = 1;
& c1 j1 I- C3 f L! ]* r3 x - ) [3 |. b: @3 }" y, G4 J
- delay_ms(5);! D7 z$ `: \$ H2 l" s) o
- 5 i/ y- J! q$ h3 O1 H+ O5 V
- }8 w9 u, I1 J/ K! G* X% [# ^3 W9 x
3 {0 u7 \' d: w7 @. ^- " m( g! [4 _! A7 h& C" [9 P8 Y: T
# Y5 T. f- v s! ~( a( a! f- //定时器3中断服务程序
/ S& _& t: J# D6 n8 ? - " V- e6 Z3 j# ]
- void TIM3_IRQHandler(void) //TIM3中断- q+ @4 u5 | h
' Y. _: x m. V+ W- {
+ Z, w3 W0 f4 D% r$ T - r) h7 E+ O9 c8 O8 o1 b4 j
- if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) //检查TIM3更新中断发生与否
: s6 y9 U$ K% ~' Y - * }- Q# r' Q" c" O1 w! T% s
- {: Y0 F3 a- @: d3 W. w
5 Y7 x1 }- V3 P( f$ S+ g- Ultrasonic_Num++;0 z0 H6 e F% {1 ?" g
! f, ]( e' n$ j, M2 r- }+ Y) k: }. B h* z" A
- - O% v1 W1 U" X$ R1 v; h6 r
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx更新中断标志, C' s8 n* {$ W+ X. \. S' R
( E; ?8 v9 ?* ?% s% O- }; l) F9 N, e/ N( D' a
0 A' }+ b& a* z9 v- * U9 }4 ^: ^5 N, n
- 7 ^+ B9 e& N4 J" S& @, G. z
- //外部中断2服务程序( u; h( i& e* ^& n! a, s. g( t2 F
' O9 R [$ W, L2 h+ C8 D- void EXTI9_5_IRQHandler(void)& ^- Z- k8 A& s% ^+ A ?
- # R. V% h% }4 J/ ~ O# Y; J, e
- {
: X: M% p- ~6 n' A
* t: y$ `. N3 @7 \- if(EXTI_GetITStatus(EXTI_Line8) == SET)! ]. l. X0 r. S, l! C
# P C3 B3 \- W, a+ D- {
& }! B/ \$ x+ f t - * H) F# I6 T7 U" ?# W: x) m) m
- if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8) == RESET)
- P; O* x* u( P9 ` - 5 G L) E `+ e( s) k
- {
2 C% S5 L ^0 W% j - # w) B0 D" ~( H
- TIM_Cmd(TIM3,DISABLE);- p3 a" w, n, ]
- + w2 i; [* Q* P; E% i
- Ultrasonic_Value = Ultrasonic_Num;
. b( E! c f2 T& R - 1 { f6 v7 J' N1 {
- Ultrasonic_Value =(float)Ultrasonic_Value*1.73; // 计算距离定时10us,S=Vt/2(减2是误差补尝)5 U* h3 p! |0 G5 Z
5 ?5 p9 f* J6 T! x$ V* B- dis = (uint16_t)Ultrasonic_Value;
' M8 I( p( Z- T6 y" I, n, M$ e
2 M1 Z- f) e5 b. m- }
+ b2 S; X$ R; b - 6 G1 \) @7 F* A! X: b/ r
- EXTI_ClearITPendingBit(EXTI_Line8);
+ |, X; j( X& B4 W - ! V# t8 B7 b! o$ c- S. R d0 Z
- }
' k2 z0 g. }+ g- C0 Z" [2 X - * k) V( @4 r; q2 @, i" [6 X
- }
复制代码
$ e& j& j+ t- x0 G2 j( C1 F 实际测算还是会有点误差的。 ) i' e" |3 m+ A8 v& \5 j' p
|