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

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

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

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

1 A$ Q2 ?9 R( ]5 \3 X- t3 b& d

6 n/ ], Z& L$ s( i3 S


1 P' V8 j! X  t( g* Q. h4 F8 G7 }/ W' E
) V, x" ^+ r1 ^4 DKS103模块使用串口/IIC接口与主机通信,自动响应主机的iic/串口控制指令。
& x' F6 f4 |0 i  T0 V包含温度补偿的距离探测,同时可以在1ms内检测光强。! f6 g9 h. ^" V1 F
* Q% x8 H7 u( j
探测范围 1cm~800cm及 1cm~1000cm(10 米)4 O1 b7 D6 o3 J
5s 未收到 I2C 控制指令自动进入 uA 级休眠,并可随时被主机 I2C 控制指令唤醒
% s: `/ o: b6 p* t/ L8 @2 b  DTTL串口模式
& Z) o' r6 w- p. ^2 G在 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 。* y7 M, K3 A* x* }

/ E  F0 Q/ t! E4 A- z) f在使用时最好使用5V标准电压,电压低会影响量程。
' v4 n* E2 y. M+ F3 Z新到手的模块默认串口地址是0xE8,可修改。
3 B3 b2 F1 d2 K这里本人被坑了,因为我到手的模块是别人用过的,被修改了地址但是不和我说,就是调试不出来。; i4 E% v' b& c8 E
当然也是我偷懒了,模块在上电的时候背面的LED会闪烁,告诉用户自身的地址,我没在意。上电后快闪两下是代表二进制的“1”,慢闪一下代表“0”,一共八位,盯着记录就能获得其地址。' C8 V7 D8 P- t
串口模式很占用串口资源,我并没有使用该模式进行开发,仅仅使用了官方的上位机进行测试,鉴定模组的好坏。

) Q0 d6 q( d) C
: Q1 b* R" k; k+ }  m
6 [4 ?, a0 M8 [, s8 I( s" p2 n% \* O# B

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


0 i" o) U; h, ~3 z/ u( QI2C 模式
8 e0 o  V, |4 j在使用iic模式时,硬件需要注意几点:
) G7 I- E( Z6 NSCL 及 SDA 线均需要由主机接一个 4.7K(阻值 1~10K 均可)电阻到 VCC ;
5 t+ w4 _. B. Y+ d, wI2C 通信速率建议不要高于 100kbit/s (因为模块的iic最大速率只有100K)。
% T0 v; I8 f0 E  c2 _  i/ _! b; E直接从代码开始:
6 ~2 M+ t$ o& j$ U因为对速度要求不高,而且为了移植方便,采用软件模拟iic。其实为了偷懒,模拟简单呀。
& S( o+ A/ Q( Q6 F; R老规矩,初始化iic。

  1. void IIC_Init(void)
    7 P/ ]/ \! B" ^3 {( |( Z) y. k
  2. 8 S8 |& i* m' j3 ]# S9 I
  3. {                        9 ]& N' x. G% Z5 k  b
  4. 7 T( p9 `9 |: p: ]
  5.   GPIO_InitTypeDef  GPIO_InitStructure;/ X& l$ ^: S3 D! y9 g
  6. ' u/ s- i5 f, u: J* X8 o. }
  7. / X6 R5 U' t* z2 D) x9 j" @

  8. ' j$ I/ u" \4 J2 V
  9.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟* g& N! b5 W9 t7 x6 D, ]

  10. . D/ b1 m; e; H3 d0 H, L/ w

  11. , p! B6 y2 T: S. U
  12.   ]: B& l+ g* I0 }" G. M
  13.   //GPIOB8,B9初始化设置( ^5 {8 S* k4 L5 t5 d7 V
  14. / N) G7 H! N7 P& F, Y% o3 u9 d
  15.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    9 B8 f- x3 T: r3 D, s6 z5 b6 G; H
  16. " d2 J, t7 i, s) A2 P4 Q
  17.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式) r: L+ E/ b4 `2 g) E

  18. , {$ |# W2 D# B
  19.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    # ^# ?% c# f+ j( L# O
  20. $ y& U, V, o7 a0 T6 R" ~; N8 q
  21.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz5 w. j3 E8 w" \5 b( a/ s/ s

  22. * H* {7 Q. Z$ a1 v% S4 g
  23.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉- c8 G, U& u+ v: m: n- z. I
  24. 4 ^3 d: k+ R/ [4 U
  25.   GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化. }/ ?3 b  f. l" ^

  26. 3 J( X6 j& k, S5 H' b% E
  27.         IIC_SCL=1;# G" o7 q: b( L8 l/ p

  28. 2 S& D6 q# G- ]/ z4 }  Q( R
  29.         IIC_SDA=1;
    3 |& x) F$ C' Q0 y% @

  30. $ q8 ?6 U& |7 ]: n. H7 _
  31. }
复制代码
0 l: ~' `4 E- M& v( x. h

/ F! ]& K7 u- _# h5 t

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

  1. //产生IIC起始信号5 u- E- |3 X8 _% v3 Q  x  F
  2. - X. `: `# N/ F7 C( J/ P
  3. void IIC_Start(void)1 d8 ?" \7 U: c: w: ~& t7 A
  4. 7 W& L& J( Z( C: I, {4 K
  5. {+ }( P0 F+ ^. t. O8 Y
  6.   U7 l: h: l" I) [; F1 L  U! s
  7.         SDA_OUT();     //sda线输出$ l& d2 P, w. n, U* k8 B( J- f

  8. 3 W' q) t3 U  v8 q0 n
  9.         IIC_SDA=1;                    
    6 w6 \' @$ h, i% Y) M' J$ ]7 Q1 g
  10. $ V9 B( b0 _4 C; J1 B! L
  11.         IIC_SCL=1;! P8 O' j+ v6 ^; k+ C5 m
  12. 5 p( Q- w$ A; }& a% n& _: L0 w
  13.         delay_us(10);
    " H: ^( p* z% {2 B& t# {

  14. * q4 Q& y6 Y  }( \. ]# m
  15.          IIC_SDA=0;//START:when CLK is high,DATA change form high to low
    # ~& V; E1 ], j- @) [; p# I+ b  \

  16. ( ~* D6 ~" G% i  C! F) l
  17.         delay_us(10);
    8 g; @) M" r8 p% P

  18. ' p! g! s/ {9 l3 u
  19.         IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
    7 `* D( m, ]9 O9 |

  20. ! @& R" \- B) s2 r$ J) L5 R
  21. }          2 a5 |  ]( G2 P$ ~5 L

  22. $ a* h7 [1 o% S
  23. //产生IIC停止信号
    2 H7 s2 y* P# s. Y6 [- O9 X

  24. $ `4 i9 O: |# T) H0 }$ V5 T
  25. void IIC_Stop(void)
    ! ]6 j3 A# c$ J, F( Y9 A6 C. v; P

  26. # K- {1 t8 M, x/ T% }
  27. {7 T" u! O( Q9 _2 G( x, A+ F

  28. 9 [* Q% R6 u4 \: B4 N5 u
  29.         SDA_OUT();//sda线输出
    * Y! ~. j8 Y- e2 u8 n, E

  30. 2 e' [# B0 m! t! j4 \
  31.         IIC_SCL=0;4 m0 Z, D9 G$ ]: S  d) {
  32. 1 V, |! r; J1 o
  33.         IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
    6 v4 W3 ^; _$ u+ u

  34. ; x7 T2 z& i/ v4 N/ U4 o
  35.          delay_us(10);
    % q, a) n+ ~; `. w# m% _5 P* Y

  36. + d+ }$ {; _- r, T; ?* a
  37.         IIC_SCL=1;
    4 W7 Z/ R1 d; W& h# j. Q" O
  38. + h9 L& {7 |0 @& J& {7 i& \4 }# `
  39.         IIC_SDA=1;//发送I2C总线结束信号
    0 }4 O& u9 C( S  C7 A

  40. 6 z3 r4 v$ k, i: V3 I) S
  41.         delay_us(10);                                                                   " Y6 t+ z$ M* o( U

  42. 7 Z9 S7 Z0 _6 k
  43. }
    ; _1 y6 V- j( h, x  T  P' u0 h, E

  44. 7 Q% h$ f" Z4 Q& x; O7 h
  45. //等待应答信号到来
    : b0 R3 d) R+ s0 L" y

  46. : K& A) q, K3 E( `
  47. //返回值:1,接收应答失败
    & J( I- R- ^: i0 _1 Q( v

  48. ! I5 X- h$ M( |6 T3 x% t& z8 y
  49. //        0,接收应答成功2 K3 B5 A. N5 P* M& o

  50. 2 T7 }1 o6 B" M) O# Y% Y& H. q  m1 v1 o
  51. u8 IIC_Wait_Ack(void)* U. U# Z% |# [

  52. 0 ^" t' H, ?0 e  f0 k5 a
  53. {
    , ?; F" R) `/ k% p; K
  54. ' }2 j' O3 D' [" O* S( H
  55.         u8 ucErrTime=0;2 h& d& u* @( s5 F- o4 a% y# g

  56. / g/ p* y) V1 K. d. H) R  `8 D
  57.         SDA_IN();      //SDA设置为输入  
    4 i* m: l" H! O2 T
  58. 5 S0 X: N0 h) l% H) M9 T
  59.         IIC_SDA=1;delay_us(6);           ; \8 c$ K! o5 a# x
  60. 2 b8 s: l( Y( r+ n1 S( z" _% o
  61.         IIC_SCL=1;delay_us(6);         
    4 v0 E2 I! q8 c' W5 x+ r9 M
  62. 1 R3 [) j5 ?* f8 X) T' K0 j% o
  63.         while(READ_SDA)
    4 P; G/ s$ Y; Y3 F) G

  64. / u6 i4 O2 |1 i& Q, b
  65.         {
    ; }: m+ n  ~/ p# I9 {
  66. ; b% h3 T! q5 ^! _1 s4 @% k
  67.                 ucErrTime++;+ {( l: F+ J2 {( j0 m9 u2 h5 ~) F

  68. % N- T3 e# \2 |4 T( l- b: b* Y* n
  69.                 if(ucErrTime>250)$ k2 {+ e, H* T: R  S

  70. # C4 l( D9 ^9 C
  71.                 {+ u  V* C2 |' R! B

  72. & d( K; r8 C/ G/ x4 n+ G
  73.                         IIC_Stop();* H4 {6 R+ x) w! z/ _
  74. / G3 _! K8 a, [: y; a
  75.                         return 1;
    0 q, V1 I9 C& R# [+ W  s8 K
  76. * s7 W8 D6 n' S6 P
  77.                 }
    0 E: b, \1 c. I, n

  78. 0 a2 x$ y7 q: g$ B' f; Y" S2 N
  79.         }
    - M" w# T% [/ |* l" S0 p6 w. G
  80. / Z8 c" f: }- X8 \3 a
  81.         IIC_SCL=0;//时钟输出0            
    4 h' d6 g: M1 c# t9 E

  82. 6 ^4 H9 P* n5 P: @* p. s
  83.         return 0;  
    / ~2 V$ }' j. n. h' [3 C
  84. 8 t8 O5 n: F" q# A
  85. } . q  L* B/ P/ \- X5 m" ]

  86. - Y& C  S7 q, C" I0 S7 M. e, L
  87. //产生ACK应答
    0 I1 u$ {; E# T

  88. " x  W$ z" {) H0 }* K8 ]' w
  89. void IIC_Ack(void)! Z% G7 I5 y6 R- U, L+ L/ Z

  90. $ _; R, e2 P# K9 A. M
  91. {
    5 j  d$ @' ^, {9 M  l

  92. : t* J" x+ h+ q2 l: A6 `; l
  93.         IIC_SCL=0;
    - d/ W+ _4 b) _- F

  94. / s: c$ y2 g! ^/ d6 P
  95.         SDA_OUT();
    8 ~) E  ]/ a4 Y  t" |7 g
  96. : P+ B7 u. ?" B+ z. {
  97.         IIC_SDA=0;: U2 x9 g! I6 q

  98. " N6 d; t0 W/ a9 w7 k5 X' j3 Y. Y
  99.         delay_us(10);: [* [0 }4 p) X9 c" l1 m& A
  100. 5 r' V+ O4 i2 q4 P* h
  101.         IIC_SCL=1;
    7 P4 C6 F8 x; h0 i2 n/ J
  102. " @( Y0 A7 U6 l  ^, E8 E# ?
  103.         delay_us(10);
    & g9 t2 C  Z% e6 v

  104. 5 x5 c+ ]9 g! R: v4 {$ x
  105.         IIC_SCL=0;
    & G# ]7 c. j: J/ e/ t4 l
  106.   s2 k' o8 `% ]
  107. }
    + |, t1 P! {8 P/ l/ W& a& Y' d0 o

  108. # a  g0 h; f5 D& m/ H' j: L
  109. //不产生ACK应答                    9 }7 Y2 s3 ~/ d- T' v
  110. ( _  i& d# [1 ?$ c- u
  111. void IIC_NAck(void)
    + W2 G" _) p; {8 }4 u

  112. , g1 l4 K. G! H% k) @
  113. {) ]4 d9 |9 }5 c$ }: [/ w

  114. ( v: O; R: A; T; e4 K4 J5 V; r9 [
  115.         IIC_SCL=0;
    + T( s- J7 ?6 L' Z

  116. 4 S, X. x! Y! h) Z  a5 L/ ?
  117.         SDA_OUT();( B+ h! G' {- j5 H. L5 \$ S
  118. " u! G& h% n% z) R. F
  119.         IIC_SDA=1;
    & d; p6 o: |& i+ f4 D

  120.   ]' j3 C, ^4 V, ]0 i& D- g/ I2 b
  121.         delay_us(10);- X* V. ?- J  Y' m
  122. 5 Z4 C: m# s# Y: q" s* |/ C
  123.         IIC_SCL=1;
    ! z$ b2 y+ U1 e5 a5 p, i: M$ G) Y% v
  124. . Z; Y; x+ s. Q2 s- r! b: ]5 C
  125.         delay_us(10);
    ' j- ~3 q+ p! }% u) X' l; \/ p

  126. % ?  \) J' \* x
  127.         IIC_SCL=0;, H, q; b1 W  R  v  ?) C$ d
  128. 7 n! U$ A5 ~0 I' _3 P
  129. }                                                                              
    & W; T0 \1 Q0 |* M+ p
  130. 9 p3 O/ s% z5 `" R0 w- m9 {
  131. //IIC发送一个字节0 S7 n- P& i4 o, ?; W
  132. 4 n. q+ P' K3 U
  133. //返回从机有无应答+ _* `+ j9 M- Y; n; r% c# g/ N
  134. 0 R, c5 {2 G3 v* M8 U6 v& |$ ~" q1 m
  135. //1,有应答
    ( {, p7 J! N$ p% F! b" d/ {1 P
  136. 7 m0 o9 C4 }/ \
  137. //0,无应答                          + ~% d4 e1 T* \! ?
  138.   _- e9 k0 g( v( S8 N* p
  139. void IIC_Send_Byte(u8 txd)+ R+ b' Z9 G" G" _1 P: O3 E9 l/ o
  140. ; W  k) V# a0 k! r9 _
  141. {                        
    9 i5 O0 }: T' E( t( C4 n
  142. 2 [+ m3 U% N: r* q% L1 h6 g" O2 E
  143.     u8 t;   
    & _0 M7 }' [! \/ C& |

  144. . ?  F3 }/ O' y/ p4 S$ M
  145.         SDA_OUT();            
    ) f# h! w  \7 F' s* O; \

  146. 3 H# t! a; w# N% b( G) Z8 x
  147.     IIC_SCL=0;//拉低时钟开始数据传输- b, |' w$ }1 _0 o4 u7 b
  148. 2 B; `% I) G4 y4 I" v' ?
  149.     for(t=0;t<8;t++)
    ( q/ r7 s5 _5 m/ ?2 s
  150. 1 i" G: |( F6 ^, K6 U
  151.     {              * [. N/ i5 b: U; Z$ c3 z

  152. . f1 ^+ h# M8 @$ S8 R
  153.         IIC_SDA=(txd&0x80)>>7;+ k* W! x% n& D/ x7 [
  154. 7 M$ R7 c3 ^1 z& |0 Z, Q+ T
  155.         txd<<=1;           0 x+ Z9 p" x9 @+ E

  156. 3 o2 M0 K6 M; n. B9 ?/ S. ]$ O
  157.                 delay_us(10);   //对TEA5767这三个延时都是必须的
    . r" S( o7 R0 ]" U

  158. 5 y( X# O9 t9 z* b2 W4 s7 W
  159.                 IIC_SCL=1;: U0 W* X6 M' m. \9 N6 C- ?: i8 A
  160. ; T7 v) D2 Z" {7 d. m0 w5 b  J
  161.                 delay_us(10);
    ( q( a3 @* _$ ]) l% ?
  162. + _" {% t$ S; a
  163.                 IIC_SCL=0;        
    # L7 v, A/ ^  C2 {. B, p" [

  164. 1 t. r5 {+ B# `# [. m+ W- l/ c+ Q" X
  165.                 delay_us(10);1 I. {% J6 J/ h
  166. 1 N- |9 |- y, ^
  167.     }         
    ) ]" I) P5 ?) F$ {' ]- R
  168. . t: g: m7 B5 S" A7 D: O. S  B9 V
  169. }            
    + r8 w7 w* D1 D
  170. # L; {6 ]9 Y# U% m* p
  171. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
    + f4 h4 ^; [6 \0 t

  172. * ~5 i7 r4 W0 c  I8 d$ h
  173. u8 IIC_Read_Byte(unsigned char ack)
    : |( E' e$ [6 b. P" r4 I7 [
  174. : B: n( k* A+ C1 b
  175. {- b6 m4 l  P" I9 o0 V
  176. 4 g3 a/ ^  `' S* n/ k3 k1 a5 `
  177.         unsigned char i,receive=0;. K4 p# g) }& n0 j) L3 f
  178. 1 K2 {1 ~7 Z0 \2 {
  179.         SDA_IN();//SDA设置为输入0 i8 N6 A; t; L5 a3 g! k8 C6 h

  180.   O. I8 v: @$ ?$ {4 H6 D
  181.     for(i=0;i<8;i++ )
    9 g5 J/ E% b0 Q. P% t1 f
  182. * n% k6 Y# t* S" b+ [2 z; g5 n
  183.         {
    : [  l  n4 n+ A" r$ [! ~: N
  184. ; v5 e0 U% D% J2 O" b& c
  185.         IIC_SCL=0; 4 G! h3 J; w- z  w8 G% l$ |8 @, y( p
  186. - S4 ], o0 M$ e9 t
  187.         delay_us(10);
    2 f- M. K% S: P% B0 W6 o$ V

  188. " ~6 N4 s3 I! `0 H) F8 B7 \, L/ A
  189.                 IIC_SCL=1;
    % ~  y. l: c* Q2 q8 T! i) T9 \
  190. ! s+ u2 t- p: p% W$ N0 h
  191.         receive<<=1;
    : m' \; V& J1 p: p8 ~3 n, j
  192. * B  {, {3 i9 D8 o/ U
  193.         if(READ_SDA)receive++;   
    1 |, _  t# A9 k, s9 g+ A8 D/ G" f+ Q

  194. 5 {2 i. Q. f  @8 W  j
  195.                 delay_us(5);
    # y% M4 q( M9 k8 Z1 b6 J8 e7 `
  196. + J0 E# `2 k5 Y* s
  197.     }                                         # H4 A4 p. K% q0 q

  198. 7 e. [7 C) Q; y; H
  199.     if (!ack)
    4 M0 i( X: v. t! }: P3 @) m

  200. 0 d6 E0 U. x8 y: ~  k5 Z6 ?+ M
  201.         IIC_NAck();//发送nACK
    , ?) D1 g  j' j

  202. ! _2 A) Y8 Y  w6 ^
  203.     else
    ! z: J0 c/ T8 y  s$ ?* o
  204. # s- z' l- R: ]/ L9 i6 M7 r3 _
  205.         IIC_Ack(); //发送ACK   
    , ^. t# q) i0 g# L
  206. * M* g) K& |8 ~
  207.     return receive;
    + Y2 b2 V' Y, g9 `2 T
  208. " p; V# B, I7 H. k1 I: B! E
  209. }
复制代码

2 b- `3 L1 h5 v/ |6 b6 M


- t( W) M, a/ E* }( M+ w8 M

写KS103的控制函数

  1. u8 KS103_ReadOneByte(u8 address, u8 reg)
    & v% M, {* F* [& G, S  ]

  2. ) U: q( ?7 Q8 L; h
  3. { ; m: B5 I) v2 y) O# ~
  4.   u( D( K# _2 J& E1 F
  5. u8 temp=0;                                                                                                                                                               
    7 n% Z- ?: i" [+ y- g& s

  6. 5 D2 f# x3 e1 _3 z+ r2 @- Q3 N
  7.     IIC_Start();  
    # M% V+ x2 D/ Z5 g2 @1 u& v5 ^, `
  8. 3 @: [* Z+ r. l$ T
  9.     IIC_Send_Byte(address);   //发送低地址! H  A+ I$ e4 n: n8 B1 q

  10. ' Y! S; I8 X3 r9 f6 W$ d7 i1 ^
  11.         IIC_Wait_Ack();         
    " E3 m0 t4 J8 h+ l& L/ d
  12. $ P/ K+ c) D$ b6 p
  13.         IIC_Send_Byte(reg);   //发送低地址8 }  }9 h$ ]$ P. Y

  14. 1 U! R3 W/ r# M$ j
  15.         IIC_Wait_Ack();           
    3 E+ Z+ [! x2 Z4 y! Y5 g

  16. 3 e" b0 I; N, e( s  W
  17.         IIC_Start();                     
    4 B: o% Q) _5 D% H* L2 o( G
  18. + n. _" h0 U6 E1 q0 l- O
  19.         IIC_Send_Byte(address + 1);           //进入接收模式                           9 c" [) h2 z1 q. x# }2 A

  20. 4 X; h7 c+ n1 ?+ ^. F  A; ?
  21.         IIC_Wait_Ack();         
    & ~( h1 R+ W9 X: c. F& \3 E9 a$ C
  22. 1 ?% C. k) T- `& E4 U
  23.   ^% S$ a; U5 g4 S5 [( H) y" X' Y
  24. % A) j% u8 f" d3 H+ z7 j+ j- Q
  25.         delay_us(50);           //增加此代码通信成功!!!
    * k% ?  X% S  w
  26. " d' h. D4 R' H& y8 A) H9 x9 _
  27.     temp=IIC_Read_Byte(0);          //读寄存器3           6 }; p/ H/ f( V4 X2 j
  28. 2 [& E, n" Z( F
  29.     IIC_Stop();//产生一个停止条件            & X( g& m* u6 s6 @
  30. : {; t5 J' S& i8 i+ [& Y  B
  31.         return temp;) t1 w) ~% l+ I4 Y5 J/ K9 H5 a7 _
  32. " w0 |6 T) Z0 p# r' d5 p
  33. }8 y( p2 M3 G# `3 ?! `) N

  34.   Q# r" }; O& H  w- m) s, W4 t
  35. 4 y$ H( \# t$ g# Z- V9 ~

  36. 9 ^3 T; h& z9 W$ d& C. A

  37. 7 n! U  d& s# U# I" m; R4 f; }

  38. 9 [  Z  x5 [8 u' Z! g
  39. void KS103_WriteOneByte(u8 address,u8 reg,u8 command)+ h6 ~7 _+ c# m  a' u

  40. 3 }( `' ^6 ^% M& R
  41. {
    / R. Y2 j) P5 V! ~* O2 r

  42. : r4 }0 H; @4 k4 l4 f
  43. IIC_Start();   
    7 T# C+ g6 E& a

  44. - ]1 W# {8 P% a. D7 Q2 {
  45.         IIC_Send_Byte(address);            //发送写命令$ l) z4 d. m* q( ]9 c
  46. & J' ?+ L. d+ ]$ e  q/ P8 Q3 n
  47.         IIC_Wait_Ack();
    + U/ ?4 x6 h. @! u/ e) o" f9 c7 `
  48. 5 n0 I* M; [, k: V
  49.         IIC_Send_Byte(reg);//发送高地址          " C, h# n9 S3 j2 y2 U: p+ t" T
  50. ) g) `& g2 q+ X- M$ ^* @& D/ s
  51.         IIC_Wait_Ack();           6 I9 Q9 f1 K. Z/ Z+ O; \1 u

  52. $ T! ~* O6 S4 O( i+ ]
  53.     IIC_Send_Byte(command);   //发送低地址" Q  |( i6 V2 f

  54. + Q7 `) S  P( B+ r+ p  Z7 A
  55.         IIC_Wait_Ack();                                                                                                               
      h# @6 N" L8 Y7 P. W4 d

  56.   O, S7 k) d$ v
  57.     IIC_Stop();//产生一个停止条件
      A& J$ K( X) L& e

  58. 2 _# g. e" Q3 v
  59. }
复制代码
1 }9 R) B" g7 f( M) t; Q8 |

( [; a. i2 I$ W; C8 m2 L1 a

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

+ m& d$ S5 T9 O/ O
探测指令从 0x01 到 0x2f,数值越大,信号增益越大。
1 f% z7 u- }2 ^; H0 U. y获取距离数据

  1.    KS103_WriteOneByte(0XD2,0X02,0XB0);
    - N1 b6 y/ T: j' V- T6 P1 W
  2. 8 \/ V8 B: ]4 |- h  N. B& a
  3.                                    delay_ms(100);  i2 G; X3 P6 a; Y( \# S
  4. 3 O) |1 \# D" v' X/ \+ M  H5 G
  5.                                    range1 = KS103_ReadOneByte(0xD2, 0x02);  j4 q9 s- o# s+ J( f! N
  6.   t4 G* T( e3 X0 j/ C( c+ j
  7.                                    range2 = KS103_ReadOneByte(0xD2, 0x03);
复制代码
4 U0 \6 z, y2 X) J

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


/ X* \3 [$ {, M
( u1 \! q( a! A  |0 j3 V% }, J7 l, m# W) n- N

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


, ]: l* o) p" h" }- B& T- d/ B
6 A3 r, e8 d" I4 P3 v" L
2 H, P5 n$ ]0 Q( T

在发送探测指令后需要等待一段时间才可通过iic总线获取数据,过早的查询总线会获得0XFF。在读取总线数据时除了需要发送模块iic的地址,还需要将模块iic的地址加1,而且在之后必须要等待,才能获取完整的数据。因为返回的是16位数据,所以这里我采用执行两次KS103_ReadOneByte()函数。; q6 b$ s% W+ m2 T# m' O
在这些都处理完之后我将采集到的数据输出到串口,发现并不能成功,range1和range2的值并不变。最后发现我是用的是0xBC探测指令,最大耗时87MS,而我只延时50ms。通过修改探测指令和延时时间均可解决问题。
6 F7 m- d) r$ T( m  j% \; ~后面附上产品手册,必须附录,没这个真不行。到处是坑。说到底也怪我粗心。下次一定,下次一定。1 e% }4 N) Q2 }9 h* B% S, Q) b. O" O
7 o3 E% ^' `; z1 v7 T$ ^
---------------------
  a/ T, r7 Q, x作者:呐咯密密

3 e7 E2 _) }  E( Q% k% }
收藏 评论0 发布时间:2022-12-11 15:29

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版