你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验之谈】基于STM32F407+KS103超声波模块测距的经验分享

[复制链接]
STMCU小助手 发布时间:2022-12-11 15:29

本文介绍基于STM32F407的KS103超声波模块的使用,包含使用注意事项以及代码配置,同时会附上本人在开发时遇到的问题以及解决方法。

. Q4 ?% b. O' y& C3 _5 x

- G) E1 f8 x1 `/ }# V  d


! d* w- r3 e6 Q: u, }2 c- q. j
6 |( e, s9 s1 [KS103模块使用串口/IIC接口与主机通信,自动响应主机的iic/串口控制指令。
$ {, z1 M- w& H( P6 D) F( t2 n包含温度补偿的距离探测,同时可以在1ms内检测光强。6 \& N# j! b- `, l; v' T

$ \: Q! h2 ~+ i. Z" e探测范围 1cm~800cm及 1cm~1000cm(10 米)' Z  @& @4 [2 f) p5 A6 f# c. C* |
5s 未收到 I2C 控制指令自动进入 uA 级休眠,并可随时被主机 I2C 控制指令唤醒
  Z( i" n& K, E; d* ^/ tTTL串口模式
3 X" |6 n* M9 _/ o9 g. j& j. _在 KS103 上连线引脚上标识有:VCC、SDA/TX、SCL/RX、GND 及 MODE。模块在上电之前,MODE 需要接 0V 地,上电后模块将工作于 TTL 串口模式。如果KS103在上电后再将 MODE 引脚接 0V 地,模块将仍然工作于 I2C 模式。因此,TTL 串口模式时需要 5 根线来控制,其中 VCC 用于连接+5V(3.0~5.5V 范围均可)电源(1),GND用于连接电源地,SDA/TX 连接 MCU 或 USB 转 TTL 模块的 RXD,SCL/RX 引脚连接 MCU 或USB 转 TTL 模块的 TXD 。+ }# a7 m/ d3 u( w% o9 D
. s. E4 r4 ^  E
在使用时最好使用5V标准电压,电压低会影响量程。- I0 |# s$ C* A- u/ T; o7 E
新到手的模块默认串口地址是0xE8,可修改。
2 U% F$ \/ p4 Z7 E0 y% G这里本人被坑了,因为我到手的模块是别人用过的,被修改了地址但是不和我说,就是调试不出来。0 o: b$ l) C( y" P8 Y. E; Y% P% u
当然也是我偷懒了,模块在上电的时候背面的LED会闪烁,告诉用户自身的地址,我没在意。上电后快闪两下是代表二进制的“1”,慢闪一下代表“0”,一共八位,盯着记录就能获得其地址。
$ s( O: u0 P, S0 A2 C& K串口模式很占用串口资源,我并没有使用该模式进行开发,仅仅使用了官方的上位机进行测试,鉴定模组的好坏。


- K8 f/ q: P9 l& z" u) ~1 `" Y7 y0 f( x) \6 S  F2 l) g6 _$ @  ^
; _; k3 O" q: V* ]. W! r' y

确认模组没问题,选用IIC接口进行开发,这样一条总线可以挂载多个模块,只需要总线寻址便可。


# H, n8 f, M* {5 H+ mI2C 模式( N# g5 t2 Z9 W( p2 F
在使用iic模式时,硬件需要注意几点:; q0 {7 f& m8 [1 S- W/ W
SCL 及 SDA 线均需要由主机接一个 4.7K(阻值 1~10K 均可)电阻到 VCC ;
* M+ h9 }' x; a% OI2C 通信速率建议不要高于 100kbit/s (因为模块的iic最大速率只有100K)。0 P  n: Y/ |- p. C7 f6 a1 |8 P
直接从代码开始:, i, i4 R. |  I* P: [. O
因为对速度要求不高,而且为了移植方便,采用软件模拟iic。其实为了偷懒,模拟简单呀。4 q2 |! ]1 ~5 Q9 w* Q# e
老规矩,初始化iic。

  1. void IIC_Init(void)5 F) H% p+ x4 h4 B( g+ u( r
  2. ! b. e) G: v2 G# k
  3. {                        3 ^3 l; ~) @& ]7 t% X' U
  4. ' m8 p; `2 o" D  z+ D  H. n' N
  5.   GPIO_InitTypeDef  GPIO_InitStructure;
    ' Y1 Y) O0 j6 n

  6.   @; i# d) h. e; X* h% A; a
  7. ( J* k0 b' e- @+ }' P5 o: B

  8. + B/ f' ]3 K: p) R( `6 I
  9.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟$ k& Y+ r* G' m1 B1 y
  10. 9 X6 N6 }* @' |
  11. " q  P, ]# ~6 o2 s/ c# R

  12. 9 U$ k1 N! j# v
  13.   //GPIOB8,B9初始化设置1 B3 R  y# {1 G! G6 k4 \

  14. 4 Q- c8 ]4 R! M: @. o
  15.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;' u- G0 Y$ n$ o6 v2 d; _) [

  16. / x4 h* o- V+ G2 @, w# T  k; i
  17.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
    6 R- X/ B- N; B" X, h/ G

  18. * W. q# ~2 c$ r
  19.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    4 g$ e) f+ g% V6 {3 d
  20. 9 Q2 `( a6 h( M7 @2 J
  21.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
    ! J: H" m. r- D5 o  t9 M! X3 Z

  22. ; B2 b& f  `# n
  23.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉1 g. {/ z4 u9 ]9 ~* U6 E3 h
  24. 8 M4 \# b2 M+ Q0 r; a
  25.   GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
    / K( v4 e9 d6 K$ t* N/ Z+ X

  26. + a2 ?# C) d9 a! Z
  27.         IIC_SCL=1;
    8 s# k2 C- l, x3 f
  28. $ D0 {. w$ y  C2 t- E
  29.         IIC_SDA=1;1 \1 V0 L# r. o8 h/ ]) b# L' v- g6 W

  30. " A8 Z( G: Y3 H0 ^
  31. }
复制代码

4 O' z7 i" Q- B1 A% K


. A+ B+ }  f) ~4 f

写iic控制函数,老掉牙的东西,全网都有。

  1. //产生IIC起始信号
    + S9 P9 J7 \0 _

  2. : C2 g8 p/ e9 W: n* T2 Z) ]# [
  3. void IIC_Start(void)6 _* X2 R; y0 U4 }

  4. ' H9 Q8 w* J8 W( l5 l
  5. {1 d) r7 D8 Y$ v% `9 P
  6. 7 m) i5 ]+ Z. s+ j- u/ o
  7.         SDA_OUT();     //sda线输出
    ' R0 ^+ t5 m2 |# M. k5 B- j
  8. ' @( c) _/ P/ s# t4 K9 B0 ~$ p+ u, k
  9.         IIC_SDA=1;                    
    # D5 d0 g( m% m/ ^( }) u
  10. 3 g3 Z' A5 H' [% N9 n3 [. u
  11.         IIC_SCL=1;# `! N1 F- V% c' o* n* b
  12. 0 i& Q$ D2 ~  _
  13.         delay_us(10);
    ! ^6 |8 t* p9 x: {$ E7 S& u" Z
  14. 2 b8 x$ n: w& ?: p9 _
  15.          IIC_SDA=0;//START:when CLK is high,DATA change form high to low
    7 C! m! ~6 B; u: `* q( T+ W
  16. ; E9 D3 ?  `/ Q
  17.         delay_us(10);6 @6 `# z+ E, e1 y7 P! n5 j

  18. + q3 o5 a+ k$ y) _. P2 {
  19.         IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 8 w( b+ t+ A) x( ]# ^( e. `) i

  20. 0 i; B' e- w0 b( \. h
  21. }          / ?- T$ P4 t) q( ^
  22. + Q' u/ d2 z  u+ N0 b' T
  23. //产生IIC停止信号
    7 V" |3 Z' k9 o) g$ z' {: E

  24. 6 j2 t+ r6 w$ U- P; w
  25. void IIC_Stop(void)7 C0 L, C3 H. m4 o: x' }

  26. 6 A0 S. A9 d2 x7 j: N
  27. {
    . l6 j5 i. K4 I' Y
  28. ) K# k9 N6 Z. {6 a; X& W6 U# k8 G
  29.         SDA_OUT();//sda线输出/ d! E7 n4 q7 B/ ?1 m7 h6 X
  30. ( `! C+ o' ]8 o. {" U( J
  31.         IIC_SCL=0;
    % L$ B' y& ^7 d) g& Y0 e
  32. 7 s! I% k) G) S7 }- T$ m; Z9 C
  33.         IIC_SDA=0;//STOP:when CLK is high DATA change form low to high  T: {/ @/ n( q  X$ h1 p5 z. N& ~
  34.   n) Q* _, J3 w5 X5 X' ]. `6 C
  35.          delay_us(10);
    1 s7 q: ?: c/ i$ A4 q& z

  36. " x6 o: Z4 E7 D; f1 ?  A1 ?
  37.         IIC_SCL=1; * f% f9 h9 s; U7 z
  38. 9 ^. l5 v' t, T  w$ h( H, [
  39.         IIC_SDA=1;//发送I2C总线结束信号& _, M# q# p" M+ q/ [, u
  40.   Q. g, w7 ?1 j, [9 g& q0 _
  41.         delay_us(10);                                                                  
    ' q9 V( U8 }2 J8 V* T

  42. / Y9 K: p" K/ I1 W" {' P
  43. }
    $ L# q5 _: A$ U# Z5 a9 ]

  44. " U: E* G' B$ j/ J
  45. //等待应答信号到来# j; m+ ^+ E6 i
  46.   @. o3 A( N9 G! j
  47. //返回值:1,接收应答失败
    1 G0 H& E  K) \

  48. ) @" ~3 C6 U5 g  T+ z4 G* R
  49. //        0,接收应答成功
    0 ~; [8 j8 X4 K4 d% r2 N

  50. 4 \" F2 c  \) j5 N1 {3 V
  51. u8 IIC_Wait_Ack(void)# f+ g* v& j( K% M& P, c# C

  52. 3 o. a, p5 l' w& n
  53. {
    ( k/ W2 D  F* t
  54. / J1 H; u) U- b1 p  b# N
  55.         u8 ucErrTime=0;+ G5 q, L) A/ \! |: `

  56. , |! t; ?$ ^' i0 l4 S& Z# a
  57.         SDA_IN();      //SDA设置为输入  ' s5 R* ?% }/ p7 a, B* F
  58. ! o" h8 s/ C9 C3 C# f; B# u% i
  59.         IIC_SDA=1;delay_us(6);           
    8 n* h. G( E/ P! H

  60. 9 [' J0 Q# A$ t6 ^: j5 e) Z
  61.         IIC_SCL=1;delay_us(6);         " Y" i& |# s$ k; l
  62. 1 o  D# Z' g  I2 o
  63.         while(READ_SDA)& @& @1 q- ]1 [

  64. 4 K: @  K# X& W/ `; {, q
  65.         {% Z3 {5 S7 v) u. Y3 R9 p2 u, T

  66. ( X5 h6 }+ e  p# q* v' e4 r
  67.                 ucErrTime++;
    9 o! w- w( H% |/ y

  68. # h3 t2 g/ A3 a8 s0 ~
  69.                 if(ucErrTime>250)3 m* h5 ^& `$ w1 _
  70. * d8 I' n1 ]* q( o
  71.                 {
    ! [7 I2 f& W1 J/ S" `' D7 z, y/ a1 ?
  72.   s7 n) o* z$ {1 q
  73.                         IIC_Stop();1 N( O4 G6 m% C

  74. / j6 f7 M; i+ m/ Q1 m' f
  75.                         return 1;
    ! L: k. B- j. i: n

  76. : ]& Z3 n; f9 G, M/ h4 M
  77.                 }! t# r6 i8 p; @* L" S( N8 O1 T
  78. . s+ ^; h$ m. g2 u- C
  79.         }
    ! L  |6 i$ ~. _/ C4 \7 `

  80. . W# G& ^! H% G; n- \' u: s# j
  81.         IIC_SCL=0;//时钟输出0            ( ~* O3 i" X5 E: \

  82. - n' y, N  \" D& ]7 r
  83.         return 0;  
    - f9 }$ G; a, D6 r

  84. % `6 B+ w8 X3 ^  `
  85. }
      S& x$ ^- s- H7 i2 ?
  86. 4 J( U, V* o1 i4 f3 h+ p  X
  87. //产生ACK应答
    / f! x1 ?( v6 x! o2 W5 q% t& z$ T

  88. # D/ Y; ^# J/ ~5 E
  89. void IIC_Ack(void)7 g- p0 ?: F2 ~! O( k  H8 g
  90.   Z( n0 k( O4 a7 k
  91. {
    1 O* `- @$ G' M* u- z" q- @
  92. # q9 Y, z3 S6 E" l/ O. p8 [
  93.         IIC_SCL=0;/ w: W/ b5 z) N; m
  94. # V& Q- N- V, x2 V  X  j% R' {, L
  95.         SDA_OUT();
    3 x& o8 F  k/ V4 d2 [( L2 ?
  96. ; t' M, o- q/ z! ^& G4 }5 P- W
  97.         IIC_SDA=0;5 ?! m( d! g0 F2 F3 u: K$ |

  98. $ r, w/ E0 t% x( F" f& v, z
  99.         delay_us(10);8 C3 Y1 F+ V2 R. s3 |9 ]
  100. , X3 K2 T, a* `5 E# B7 \
  101.         IIC_SCL=1;
    $ p( t! s  p, ]  n; z

  102. 8 P( ]" g2 \: Q6 F3 v
  103.         delay_us(10);7 X+ f! G- W/ _

  104. 6 i! [, r) U, Y, \
  105.         IIC_SCL=0;
    4 J: J& r5 i, J0 x
  106. 0 A# r2 b2 k& i7 g6 D8 O
  107. }& g% C0 ]3 Y: z
  108. ( M3 x! @; z7 }- c) N
  109. //不产生ACK应答                    
    + @, n) Q6 R/ G' M+ j- I: ^* g

  110. ( B2 j5 U; Q1 X
  111. void IIC_NAck(void)5 q9 Z8 H2 w; A8 N7 ~% I
  112. 1 C, _3 w0 V3 B1 u
  113. {
    . ?& p; Y% w* d0 v

  114. 7 H" s' T7 ~" z. U7 X8 b3 j
  115.         IIC_SCL=0;
    : j- \# X; `. \5 H# c) f
  116. 6 ~' @. W  ]+ F
  117.         SDA_OUT();
    # @: q1 u# b: c8 p: s/ `% [6 ~6 O% Z6 l
  118. : [* X- G+ v0 }. e
  119.         IIC_SDA=1;
    % D8 e) I/ Z" G0 H4 A8 Y4 s

  120. 2 O3 M# \5 J* B/ i+ e: z
  121.         delay_us(10);3 }+ q5 u: s( Y  X- P& l
  122. 7 N$ \, I. M: D( H: p- Q3 E& q( H
  123.         IIC_SCL=1;
    ' F) m/ [* F2 X# Q

  124. ' l" H- H' H; \- j. Q
  125.         delay_us(10);8 ~" q* ?: H* A& B) Q; m8 U, T
  126. . r5 [/ r6 Y. b# L( B  A6 N
  127.         IIC_SCL=0;# h" a, I2 G, C$ Y/ o
  128. * k8 T' K& E7 M. ~) C: l
  129. }                                                                              
    - H( I- L0 B0 g+ L7 y, c0 }3 }9 a
  130. # \$ ~8 G/ s; }+ ~0 m* v' @
  131. //IIC发送一个字节
    , z2 B# h5 ^4 O! r. F

  132. 5 Y+ g* f- i8 U) p, ^/ v1 u2 h
  133. //返回从机有无应答
    4 I) ]0 B% k# s: ?" L  K
  134. - f$ ~7 M$ W2 D: t
  135. //1,有应答
    1 v4 Y5 t" ~) g2 b

  136. 4 `/ C1 ]+ c) q3 e, \5 q4 ~7 v
  137. //0,无应答                          
    - ]9 h/ c4 i& b: S7 I
  138. , D6 O6 r& t9 {5 c# `7 v
  139. void IIC_Send_Byte(u8 txd)- O' W2 ?7 h* z2 E, s5 a9 i

  140. * m2 H# }$ n6 o: g$ c8 x0 `# \
  141. {                        7 f" \! ~* J+ i6 _
  142. ' d8 q% \! O, ^" i% C. e1 w0 m: t
  143.     u8 t;   + R0 n4 [. U# Z# ~& w6 P( y
  144. + p( c- W0 r" e- \, B( D0 C
  145.         SDA_OUT();             * d, ]% }. w  T3 o  L- A

  146. / a3 n3 Z* C. h' S, N
  147.     IIC_SCL=0;//拉低时钟开始数据传输
    6 G+ O5 A9 b: Z* V

  148. 0 `/ s6 e% g3 ^0 O
  149.     for(t=0;t<8;t++)
    : h& Y, M- Q; r5 S
  150. & N0 ]: j6 ~$ J* d; Y/ l4 s7 ~
  151.     {              
    : j  @  u. v' w' I

  152. ' I6 `9 N) j& }  `- x. H
  153.         IIC_SDA=(txd&0x80)>>7;
    1 m! c* r- ?$ g5 t  {
  154. : D3 a9 A# k% o( J
  155.         txd<<=1;           
    1 g6 ^1 s7 J) D6 P/ X
  156. ; o: m# ?7 \" T( x* F3 b3 K; c, J
  157.                 delay_us(10);   //对TEA5767这三个延时都是必须的
    . N  G; m+ X7 ^0 T3 [+ \0 v
  158. / V& L- V2 w/ C" i; t) J/ I' G4 q
  159.                 IIC_SCL=1;8 G+ Q" L% ^& a3 m7 i5 U: S, t+ S: [

  160. 3 E# ]! s( w* q& {( |6 w
  161.                 delay_us(10);
    1 {! E0 m& F* Z0 U! Z
  162. 6 E1 W" Q) V9 Q8 |# A, g
  163.                 IIC_SCL=0;        $ k: ]6 N# |" ?' M- h

  164.   u' B, ~/ U# h
  165.                 delay_us(10);
    ! T, Y% {0 M" q" r* o

  166. 5 D" o) x# \8 v
  167.     }         
    + q% z  B* X3 a/ c# K9 x& u

  168. 3 T3 q8 C* F% V0 P
  169. }             7 d4 s+ D  _4 @* S4 h

  170. # S+ g, K1 i% I" j  g
  171. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   3 }1 m' [& i1 a1 V- k6 e/ T
  172. % X& l$ Y. |$ R6 {, G7 ^4 Y$ T7 J
  173. u8 IIC_Read_Byte(unsigned char ack)* p! `/ Z3 y; m/ ~

  174. ) N4 I$ _6 g3 P9 k
  175. {
    6 w- n( S' h, J& K- v% Z* F+ h0 z" V" \

  176. 9 ]* a7 G, X. j# C8 `$ N
  177.         unsigned char i,receive=0;8 ^+ n6 x/ l$ o, G
  178. 4 i6 h: K" _3 N' y1 B
  179.         SDA_IN();//SDA设置为输入. U% s: ?3 K6 |% m. P

  180. / x: d$ f& h. S/ W9 h8 \7 J% g- r
  181.     for(i=0;i<8;i++ )! k4 M1 u1 M( ]# Z1 g; P0 T; b+ R
  182. 0 w% n& m: ]. n! `# V: x
  183.         {. U* {1 g# d& L0 L, S5 s
  184. - L' O( `- ^; T, A# C6 D# K% [
  185.         IIC_SCL=0; 1 e$ P4 r; Y3 A( I# S6 W6 k8 v

  186. ' k( [' [2 {. y, J, C; X( t
  187.         delay_us(10);
    " }; `. C$ ?, y4 S1 u. B4 Z' @
  188. 8 [* p1 O5 s" \
  189.                 IIC_SCL=1;
    . ~+ _6 i; \5 Z* k
  190. 1 t: h7 C# F( K$ M( N
  191.         receive<<=1;
    / l3 D. I' }& l' H

  192. % D5 K1 M& h" c4 E4 v, y
  193.         if(READ_SDA)receive++;   2 @( @* m: V2 ^# f* T& [
  194.   R& d) Z+ e# D8 Z
  195.                 delay_us(5);
    ( N7 Q0 v7 p/ [/ {+ ~& B

  196. , X8 @4 U* ?4 c/ k9 s
  197.     }                                         / [+ m+ p- h& n" w* {

  198. . Z8 G. h& q! ]- Y: r+ t) E5 b
  199.     if (!ack)
    " z- v4 U$ Q# d6 ]9 }  L

  200. / x: ^5 \1 I8 n) a8 N0 d
  201.         IIC_NAck();//发送nACK
    7 K+ l- j( O! Q

  202. + j, H1 `; }& v+ H- r
  203.     else( f, c7 {3 ]! o+ N
  204. - @2 w8 \" u! [& f
  205.         IIC_Ack(); //发送ACK   
      y5 }: n) v, w$ w9 s
  206. " U! |+ V& m0 g$ f5 }
  207.     return receive;3 g3 W. a+ C& @" ?
  208. 2 P4 k) ]6 M7 L9 r% i0 P* i8 R
  209. }
复制代码

2 L/ d* I" g& D) o; C

) n/ y) K1 |" z, V. K6 b1 [) G

写KS103的控制函数

  1. u8 KS103_ReadOneByte(u8 address, u8 reg)
    6 ^) j9 y- X" `5 G) W

  2. 6 j: v" p8 o# y2 P
  3. { ; y0 X! |- ~( c9 Q4 }" Y; @* d

  4. & Q* p1 ~" ~. |: F8 R/ M$ u" H
  5. u8 temp=0;                                                                                                                                                               ! C5 `9 j. h. c3 ^8 j
  6. : U0 X9 l0 O) w6 H( {1 e9 |+ \
  7.     IIC_Start();  " s* G8 v( M! g
  8. # d/ f8 z4 k) r; b6 T2 g
  9.     IIC_Send_Byte(address);   //发送低地址5 o% _9 y1 o* a$ o% ?
  10. ( Q1 c7 M& F, f% `3 E8 i
  11.         IIC_Wait_Ack();         
    " N& I" X' b. ?+ g4 I, ^1 G

  12. 6 p6 }& d# g: v
  13.         IIC_Send_Byte(reg);   //发送低地址
      U% F# |) R7 d6 V0 M7 A4 T
  14. " F; H+ p/ h" V  M" n( F: M$ Y
  15.         IIC_Wait_Ack();           2 Z0 q+ Y7 Q+ m! B1 N% a: g

  16. 4 P0 ~( |0 @5 G
  17.         IIC_Start();                     
    3 Z4 c/ z+ r4 l: i' [
  18. / N0 f: r& r: T: T- Y7 o% M' ?: C
  19.         IIC_Send_Byte(address + 1);           //进入接收模式                           
    * D/ z$ i( _2 I: N0 I% Z
  20. 1 i: V& Z* \/ R& F8 o% x" f- U
  21.         IIC_Wait_Ack();         
    " r/ ^# u" K1 k5 n  v3 N' w

  22. , r/ l2 m! J) M% s- Y
  23. 7 B! j4 @5 }2 j. V. v
  24. / d* K, U; D& i" F! P9 M' j
  25.         delay_us(50);           //增加此代码通信成功!!!2 x) @. ~0 A* i) _+ u

  26. & m+ E* Z* Q, W3 u
  27.     temp=IIC_Read_Byte(0);          //读寄存器3           $ F5 q% n9 A* x& T6 \

  28. " P+ Z. \1 _4 F, H8 V
  29.     IIC_Stop();//产生一个停止条件            
    1 @& Z( A. }- b2 x% O0 h

  30. " X/ P: T' [* Q0 ?  O
  31.         return temp;, O% T5 n  @- @5 @. n: ?1 g: o

  32. . P0 Q7 i4 [2 w. K1 f/ u
  33. }
    ; _! {/ W# t) G3 d. O  p- p

  34. . Y. t) q; w8 H
  35. / U1 _7 I* ^$ v" \3 {8 E8 J

  36. % R; W' h& R# o1 P, d6 ?' c

  37. ( S8 m1 \7 c# H: k
  38. $ \: f; G0 A: X
  39. void KS103_WriteOneByte(u8 address,u8 reg,u8 command)
    ' f0 u+ V! [# Y% X/ |: g

  40. + S$ |6 E, s/ J3 d8 }
  41. { " @: s8 z1 V/ L7 H! t5 E6 g

  42. . h/ g5 r3 R& c/ ]
  43. IIC_Start();   , e5 H% U+ X+ G' A2 H: {
  44. 9 B' a+ N+ i' ]
  45.         IIC_Send_Byte(address);            //发送写命令7 f4 `( ^% D% U% ?6 K$ X4 u% y2 E
  46. 1 n) b: i* i9 a# g5 d1 `9 D* g
  47.         IIC_Wait_Ack();
    . o" @( _2 h8 Q  y4 R7 D% X1 B

  48. + g9 C& p& f& q) E' P4 x
  49.         IIC_Send_Byte(reg);//发送高地址         
    - }" j- a- ~2 n7 u
  50. + C" q( ], U; w( S
  51.         IIC_Wait_Ack();           
      f4 s9 g. |" R9 f  p5 @

  52. $ E% Y- Y) ~! j2 m8 H
  53.     IIC_Send_Byte(command);   //发送低地址" ?/ W- q3 F6 `2 y# r! Y
  54. 6 T: g. [  {) k/ I+ H
  55.         IIC_Wait_Ack();                                                                                                               ( r: E9 ~9 s# d% ?( {

  56. * Y  N% e# T$ o6 {
  57.     IIC_Stop();//产生一个停止条件 $ L( K9 q" o. T8 _% K- I

  58. " C( Y; G: X1 R* S8 C3 m# t8 q
  59. }
复制代码
9 }( |. t+ z! W
# s0 n. S: L( \# a' q: J' C

这里依照了模块的指令发送流程:

- @# i* k# d& G3 R$ K+ `
探测指令从 0x01 到 0x2f,数值越大,信号增益越大。8 U! P4 B5 z; J5 D
获取距离数据

  1.    KS103_WriteOneByte(0XD2,0X02,0XB0); / \$ K! h1 X" }; W) N" Y. ]2 {
  2. : @' r/ X2 ?2 R  k
  3.                                    delay_ms(100);4 g* }. y5 [/ R

  4. & t/ ~7 o  \; h" [3 Z
  5.                                    range1 = KS103_ReadOneByte(0xD2, 0x02);" m! S2 n# t8 H

  6. % Y+ t3 n; s: u+ z
  7.                                    range2 = KS103_ReadOneByte(0xD2, 0x03);
复制代码

3 O  n  f3 J8 }+ u/ D0 J2 N) W

每一帧的探测指令格式为:


7 h) j; ~4 u4 R  K  d( U9 D: f8 u, @$ h+ t7 Y& j# B

3 i" p; N0 l; m4 ^

KS103_WriteOneByte(0XD2,0X02,0XB0); 中,0xd2为模块的地址,02为寄存器地址,0xB0为控制命令。


* ^  P; f& d% Y/ ~# a  r. C3 r3 q' G, `3 W. Y2 }" P
9 i* {# G$ k* G- T) J/ z" _

在发送探测指令后需要等待一段时间才可通过iic总线获取数据,过早的查询总线会获得0XFF。在读取总线数据时除了需要发送模块iic的地址,还需要将模块iic的地址加1,而且在之后必须要等待,才能获取完整的数据。因为返回的是16位数据,所以这里我采用执行两次KS103_ReadOneByte()函数。7 H# _7 |, R3 C
在这些都处理完之后我将采集到的数据输出到串口,发现并不能成功,range1和range2的值并不变。最后发现我是用的是0xBC探测指令,最大耗时87MS,而我只延时50ms。通过修改探测指令和延时时间均可解决问题。
* \, ]5 I1 A7 K+ B0 c2 P1 ^后面附上产品手册,必须附录,没这个真不行。到处是坑。说到底也怪我粗心。下次一定,下次一定。
8 P/ N; z* @! X. L0 e  _* `7 q& F) c! r2 g% k, X% Z5 F" ~) K/ k5 [
---------------------
! @& T; h/ s! J6 X( h作者:呐咯密密


5 p) b9 H' H: V6 m
赞 收藏 评论0 发布时间:2022-12-11 15:29

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版