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

STM32F103+VL53L0测距(一)

[复制链接]
STMCU小助手 发布时间:2022-12-7 16:03
本文记录了我使用STM32F103结合VL53L0测距模块的一个学习过程。
( Z% l3 D. C) R! q8 X5 CVL53L0是由ST公司最新推出的一款飞行时间测距+手势检测的微型模块,它应用非常广泛包括:激光测距、避障检测、一维手势识别等;接下来我们重点介绍它的激光测距功能。' E6 `' K7 J' r
" j5 M/ N! p3 c
一、模块的硬件连接
+ x0 U- _* q, I
$ O" P# @' r5 P2 h
20191215095427730.jpg 6 Z- S: [# p5 D8 c
20191215095607206.jpg
7 u" L. T/ P" q5 X" _7 v9 n. {% l: q* X/ M$ k, w& @, o
上图便是我所使用的测距模块GYVL53L0XV2,它预留了六个接口:
5 p8 O5 X. ?2 h* X1、VIN:供电电压,可在3V~5V范围内进行供电,但如果自己进行电路搭建的话,则需要一个线性稳压电路,将输入电压稳定在2.8V进行芯片供电和芯片I/O端口的上拉,这个可以自己看它的数据手册;
2 |1 v: M! i+ S! P& G2、GND:参考地;: r9 V; N+ N: j1 Q# C' t4 Z
3、SCL:I2C通信的时钟线;3 y: H) L$ K2 e! G: @( _! s
4、SDA:I2C通信的数据线;
9 L& ]8 b/ s9 z( f  l5、XSHUT:芯片的使能管脚,电平1代表有效,电平0代表无效;0 K/ Q8 R  m9 M9 K. ~
6、GPIO1:芯片的中断管脚。
5 B9 K( o0 C& E: H/ A3 F
& O9 c4 s- M8 t" N2 A* H- j
本文与STM32F103的连线如下:
/ j& R; j" y# ?# s. i+ ?VIN--------------->3.3V
5 q2 o; w+ P- R8 K) pGND------------->GND; m' D0 M" ?6 j/ W
SCL-------------->PB6% O6 J! d' e) c. }- R
SDA-------------->PB7+ w9 }+ ~& I  a2 ?4 m# a

- b8 ^& j5 w  j# ]其中XSHUT与GPIO1没有连接,由电路可知,未连接时它们均上拉为高电平,XSHUT一直为高则代表芯片始终有效工作,如果有需要也可以进行连接,用单片机控制。在这里我没有使用到,因此直接不连接就行。" _2 e8 P8 N# @, t: W

$ [% D2 C9 }1 ]
' m4 |% O( H+ v- E, W* Q$ h! {
二、程序代码
' H9 ?- H' z+ M; T# S
  1. #ifndef _VL53L0_H+ t6 Y0 f3 k& W1 u( K# @1 w
  2. #define _VL53L0_H
    ( J5 i2 l. L5 G3 J, @" ^& z+ f

  3. 2 d+ a1 n. B- Q/ t( Q
  4. #define VL53L0X_REG_IDENTIFICATION_MODEL_ID         0xc0
    , N* B- t& F$ ]7 j8 J+ Q
  5. #define VL53L0X_REG_IDENTIFICATION_REVISION_ID      0xc2% B4 |7 O7 D8 t- A+ E5 |# U
  6. #define VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD   0x50! q0 m7 x7 {; Y  ^: A
  7. #define VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD 0x70
    ! [0 _6 B  }% e
  8. #define VL53L0X_REG_SYSRANGE_START                  0x00. g( C# A: F+ ]+ W: p. x
  9. #define VL53L0X_REG_RESULT_INTERRUPT_STATUS         0x139 \* x  J3 V4 \
  10. #define VL53L0X_REG_RESULT_RANGE_STATUS             0x147 E( O& `' M" M
  11. #define VL53L0X_Add 0x29
    9 }4 J* }3 g+ [, \$ {
  12. #include "stm32f10x.h"
    1 D* K; l0 `: ]; r# {
  13. #include "bsp_usart1.h"% T- U* C3 M3 x! g, M
  14. #include "bsp_i2c_gpio.h"
    2 u2 J$ c& |& E) `0 e5 X2 [
  15. 0 x7 d; ], T5 m- ]2 `$ }3 l
  16. u8 VL53L0X_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf);- ~4 B1 V# A- ~3 g  F. L. {( v
  17. u8 VL53L0X_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf);8 a, ?# O" P" L6 a/ B
  18. u8 VL53L0X_Write_Byte(u8 reg,u8 data);. d; k) f& Z  s" u
  19. u8 VL53L0X_Read_Byte(u8 reg);9 |; C# }& z3 c
  20. uint16_t bswap(u8 b[]);                                  
    * ?  `1 |0 L2 }1 L( }' l
  21. uint16_t VL53L0X_decode_vcsel_period(short vcsel_period_reg);        9 }3 a, W9 |$ V$ K
  22. uint16_t makeuint16(int lsb, int msb);                 
    ; ?" f! O) m% i. a, d' |6 L

  23. , q  A8 b! @8 g
  24. #endif7 H0 _8 U* E% M2 w3 h+ ?6 O$ K
  25. + F! j2 e! S7 z" q
  26. #include "VL53L0.h"
    & i) @( d1 I1 u7 @, U' ~$ @! ?+ m  J
  27. uint16_t bswap(u8 b[])
    * f0 Z% f1 N4 B+ B9 D
  28. {8 Q3 b  P/ ^8 e: C4 h# m. E2 G9 A
  29.         uint16_t val = ((b[0]<< 8) & b[1]);
    0 @5 Q- Q3 y3 h9 B+ H0 N( g
  30.         return val;
    $ q# C9 }) I. h% w+ A
  31. }
    9 N8 a1 M* A$ T+ G
  32. 1 @1 h& }! h( p4 D% {- r- u& q
  33. uint16_t VL53L0X_decode_vcsel_period(short vcsel_period_reg)8 T( Z1 v5 S6 t; Z: Z+ s/ j" N4 _# Y+ t
  34. {
    ) u, A6 S( L7 S0 h* J" h
  35.         uint16_t vcsel_period_pclks = (vcsel_period_reg + 1) <<1;& r: A) ^9 V+ ~, |4 q
  36.         return vcsel_period_pclks;
    + |) ]1 l% S4 I: w& b% ^
  37. }  H9 }( P9 ?8 p1 Y& H( b5 ^1 ~
  38. , D5 R0 n9 l1 d4 E2 r# b* e" d
  39. uint16_t makeuint16(int lsb, int msb)- ^$ v& Y8 K4 j0 k( C$ g/ h  g0 u
  40. {
    ' c, h) c( L4 d3 ]
  41.     return ((msb & 0xFF) << 8) | (lsb & 0xFF);3 b  q, A! O+ d
  42. }* G/ f$ _) _* N' }9 _3 R2 F

  43. & p8 q& V8 M; \) p: B2 n
  44. u8 VL53L0X_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf)+ E" s) ~5 u" S; \0 V
  45. {
    ' @  {* ~. H3 s% ?7 A% `
  46.         u8 i; 9 g: m& T5 I. v) Z
  47.     i2c_Start(); " ~  H% ?4 O6 N+ q8 T
  48.         i2c_SendByte((addr<<1)|0);
    " j) M* K4 m( R# P( V
  49.         if(i2c_WaitAck())
    ) T* @0 A" c/ b5 d, Z
  50.         {' u. S# @% {" A0 @  }
  51.                 i2c_Stop();                 
    7 ?# [0 T7 ^& e+ f- Z( M4 P
  52.                 return 1;                ( q2 v5 H0 ~: s4 v
  53.         }
    1 X3 C0 _, @% E, i
  54.     i2c_SendByte(reg);' r: E& B0 K1 h; x- n* U
  55.     i2c_WaitAck();               
    / F2 l, p1 q% h% Q% R: |) m
  56.         for(i=0;i<len;i++)
    5 t2 F6 |/ t# p
  57.         {3 J5 l6 G: z' \6 D
  58.                 i2c_SendByte(buf[i]);       
    ' ]- ~$ z  x- I
  59.                 if(i2c_WaitAck())                8 L$ x7 F6 d# a5 J& h: N
  60.                 {/ d# }5 M& [7 ~- \
  61.                         i2c_Stop();         
    & h( A+ z- `5 a6 {( `
  62.                         return 1;                 ! T0 T. s8 X8 U+ ^8 U, T
  63.                 }                - t; [! b8 ^. f3 a9 }0 H! _+ o( ?
  64.         }   
    2 ?( V* I- R+ @0 O
  65.     i2c_Stop();         
    , w. P/ p; n+ R$ \- }
  66.         return 0;       
    - _7 W' T3 t5 c" T+ u+ M
  67. } ! t4 T& s0 c2 @- @- S

  68. 9 `; ]: n9 _7 L# G
  69. u8 VL53L0X_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)! I+ G  s5 U* k+ V
  70. { - s; B1 x9 Z# ]3 a. Q, `
  71.         i2c_Start();
    ( J# e6 c+ |8 ^  [. D9 ^/ }4 e. P5 }
  72.         i2c_SendByte((addr<<1)|0);; [- P5 ]" B2 T$ r1 \# K
  73.         if(i2c_WaitAck())        : {" T) ^" A4 O" d' V* ~& K2 j
  74.                 i2c_Stop();                 
    4 c& I$ k& E  N8 d3 S9 @8 ~
  75.                 return 1;                0 z! q: A* q# T, b
  76.         }$ \3 X4 m2 K0 }& A2 c. t1 e0 ~. x
  77.     i2c_SendByte(reg);       
    ! ~% k+ p% j* r/ R& n1 O
  78.     i2c_WaitAck();                ; n1 U* ^; `4 X' I8 q7 \" I
  79.     i2c_Start();+ Y1 E) z' K) h4 v* |+ u6 _" W
  80.         i2c_SendByte((addr<<1)|1);        # D8 D9 z% p1 _! w
  81.     i2c_WaitAck();                ( U- I$ n' }3 @4 u* l7 I; a# j
  82.                
    ! ?0 {7 g/ U# @
  83. while(len)* T3 y5 W" v3 p3 \1 V$ A$ R( F. q
  84.         {7 N3 S9 l! Y0 X3 k) Q
  85.                 if(len==1)
    - ?% L$ A2 R2 j
  86.                 {
    # i9 D! \, P+ }3 j& R+ c& m
  87.                         *buf=i2c_ReadByte();
    9 L( G- S% y6 n0 o; m$ b: [. t% U
  88.                         i2c_NAck();
    - ^0 t9 m; p% Q  m9 z& l8 H8 V8 K
  89.                 }
    3 l7 d  D8 r" E+ N* n- ~
  90.                 else 4 N" `, |! f' c( z# T6 K! `
  91.                 {1 w( ?$ q: L1 D1 d# a
  92.                         *buf=i2c_ReadByte();        8 _& |/ y, l& v2 `, d5 s! T- j
  93.                         i2c_Ack();/ v6 c+ W- Z$ d* W4 T
  94.                 }
    $ y2 k. w, k  B# T) w" r
  95.                 len--;# X4 y0 Z; k* S8 Y) D( h- i$ d2 ?
  96.                 buf++; * d. P4 n4 e3 [' M8 W3 H
  97.         }   
    & S) [( J6 ^  b9 x- I/ _9 n
  98.     i2c_Stop();8 H8 K# f7 s1 N1 K1 ^& r
  99.         return 0;        9 G8 y  I, \6 x- ]+ _
  100. }
    ' v/ M% c; h6 S
  101. 3 ?9 g! j, c" Y
  102. //IIC写一个字节
    ) N' \; S% {; b. A- H
  103. //reg:寄存器地址7 H9 O6 o% V* M5 {% @
  104. //data:数据
    6 H# a6 U2 P! f) Z4 S8 S6 R
  105. //·返回值:0,代表正常
    8 R& |9 L! l+ T- r! ~8 j
  106. //     其他,错误代码
    # |, w" G" z* x- y
  107. u8 VL53L0X_Write_Byte(u8 reg,u8 data)                                  7 K9 }9 {3 s, ^1 U
  108. {
    % l  |' g8 ^( R/ n. w8 m% t1 {
  109.     i2c_Start(); & g' @+ Q2 l6 L$ F4 Z, T
  110.         i2c_SendByte((VL53L0X_Add<<1)|0);//发送器件地址+写命令
    4 u5 ^( n% x2 X! a
  111.         if(i2c_WaitAck())        //等待应答
    * g* f- q5 o# H0 p+ `0 \
  112.         {
    + Y* X4 E7 W( o4 {5 ]) j
  113.                 i2c_Stop();                 & f6 W3 t" I- S% z
  114.                 return 1;               
    ( _  y  H- ^" _8 @4 t! `- A
  115.         }5 ~# t/ ^: j/ I3 o
  116.     i2c_SendByte(reg);        //写寄存器地址
    1 X" U2 f! }' z
  117.     i2c_WaitAck();                //等待应答0 k  e& L6 ~4 A, ~* L, p' ^# @( b
  118.         i2c_SendByte(data);//发送数据7 V& H" L" P7 c, s3 E, N- x
  119.         if(i2c_WaitAck())        //等待应答
      c& N7 @! Z  ^0 g, f$ j) ~3 S
  120.         {2 l" B, o+ B" B( g& s' n
  121.                 i2c_Stop();         * U% z3 Z! f8 m, ~
  122.                 return 1;                 
      R1 e' I2 ~+ S& m0 K
  123.         }                 8 {) u3 n2 ]. r& M+ m
  124.     i2c_Stop();         
    ' _5 a# P3 U: j9 u% m  q" e) w; Q
  125.         return 0;8 W% F4 I/ N/ l
  126. }
    " a, l. S6 u# A
  127. //IIC读一个字节* v1 x$ w0 \+ N
  128. //reg:寄存器地址
    $ F8 A6 K# p2 |# a) b
  129. //返回值:读到的数据
    $ x% Y) g  j; S: N  F
  130. u8 VL53L0X_Read_Byte(u8 reg)
    " J4 @( x1 |9 ]1 C
  131. {
    # g/ Y1 o) k4 c& V' [! K
  132.         u8 res;
    3 l7 y; g1 t& K$ v
  133.     i2c_Start(); ) _$ R% ]" ?% n$ U" o( q! B. M
  134.         i2c_SendByte(0x52);//发送器件地址+写命令       
    ' E) `9 W& X4 s. O9 b( v3 J$ z9 n% Y
  135.         i2c_WaitAck();                //等待应答
    6 J9 O; O) W: `8 B3 m
  136.     i2c_SendByte(reg);        //写寄存器地址' l9 b  a5 \- n& O$ ?3 @6 b
  137.     i2c_WaitAck();                //等待应答8 [* O4 [% W- a& i$ u- G' n. y0 R
  138.     i2c_Start();* b1 O5 y) v3 E8 g. s' `) E
  139.         i2c_SendByte(0x53 );//发送器件地址+读命令
    3 ^- D/ \4 y4 C9 R6 L7 @
  140.     i2c_WaitAck();" E( B0 d$ A& k' i4 g! u
  141. i2c_SendByte(reg);    //写寄存器地址
    1 K+ L8 K1 f4 Y+ Z2 r* P
  142.         res=i2c_ReadByte();   //读取数据,发送nACK
    ( l" C! j1 \6 H( s/ g3 q
  143.     i2c_Stop();                        //产生一个停止条件
    & C) l% l  x! q# K  ]" }
  144.         return res;                ! A% R5 V' g/ x8 b$ P$ D: C
  145. }8 }8 L- e* k2 J6 ^
  146. + f8 V$ _8 S$ e/ B- p* d
  147. main.c:
    7 ]+ T& E$ u/ J) _5 k
  148. #include "stm32f10x.h"* `# g% k; G+ i! |5 [( u: W) h
  149. #include "bsp_usart1.h"
    3 Y+ c+ w$ a8 m  C1 l
  150. #include "bsp_i2c_gpio.h"
    : k* B( p, K0 r( k# Q) ^. Q/ \' J
  151. #include "VL53L0.h"* d5 R7 s  t& M1 P6 a+ k1 n% |
  152.   n5 N( x$ Z) v$ r$ d& J6 W
  153. uint8_t Rxflag=0;
    ! M8 H6 \: i# `. b4 g2 ^0 U" C
  154. uint8_t ucTemp;" X" E+ y5 h+ f# g% z

  155. ! ~2 j$ R4 F5 s- ~
  156. int main(void)+ P( H% I# \7 h
  157. {        / u/ @5 f# P$ w' r' L3 G, Q
  158.         ! P5 y! T* X7 Z, \8 J6 a: y
  159.         u8 val = 0;
      K" Y- w2 D8 Q
  160.   u8 gbuf[16];
    9 @- t0 w2 {2 I) Z% P
  161.         u8 DeviceRangeStatusInternal;
    ( A% X+ m$ r% h- c/ C' t; l  D
  162.         u8 tp=0;
    ! i+ O1 v- c4 u( j) l8 E( \6 s
  163.        
    ) ?7 G. w7 X8 t( @+ S
  164.         uint32_t cnt = 0;) _7 M+ n; R" M% l* I, u6 V. e
  165.         uint16_t count[3];
    ! B. D, c( A! z
  166.         $ Z8 J0 O# C7 E+ i
  167.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    3 D. {. z7 k9 E" s+ f$ W
  168.         USARTx_Config();
    1 n( S7 {" R  e. K/ I* d  {1 q
  169.         NVIC_Configuration();( H5 e" o- N+ d3 m
  170.         InitSysTick();
    & d8 l1 y. w* n* L% j
  171.          bsp_InitI2C();/ s$ b! X5 G3 ^. T
  172.         while(1)
    7 l5 M% D2 k* K7 R- U* n
  173.         {9 [  |1 t0 l( L0 H
  174.        
    - P! `: R) k/ |) ~
  175.           VL53L0X_Write_Byte(VL53L0X_REG_SYSRANGE_START, 0x01);1 W) d4 v/ Z  u  ?
  176.           
    + H8 {- O7 |0 j/ l  k) l# `# G
  177.                  while(cnt < 100). I8 o/ r) o" Q; D" t2 A
  178.                  {/ B6 Y' }8 K4 e
  179.                                 delay_ms(10);
    * X! p+ w# S8 W1 T- e
  180.                                 val = VL53L0X_Read_Byte(VL53L0X_REG_RESULT_RANGE_STATUS);0 O; L5 r8 b; F, [  `3 \
  181.                                 if( val & 0x01) break;) S8 X# V+ L- j6 |
  182.                                 cnt++;
    & p, ?% U9 h- @9 R$ j
  183.                  }8 G' @7 S) ~" m; F* u$ R8 X

  184.   C" J/ l! B# j4 d$ P0 f; O, `. q2 B
  185.                  if( val & 0x01)6 C0 X% B: h/ A, d* G- o" w  C
  186.                                 printf("\r\n readey \r\n");; A- }/ @: P! }4 k9 U; ~3 ?) ^6 n
  187.                  else1 T/ Z6 w% w$ G3 p
  188.                                 printf("\r\n not readey \r\n");. t# o: S* O. B- s" c: C
  189.      VL53L0X_Read_Len(VL53L0X_Add, 0x14 , 12, gbuf);/ H' p( U" K4 ]+ i" n0 k: g0 s" s6 c+ [
  190.                        
    7 e. H$ c6 N8 B  L
  191.                  count[0] = makeuint16(gbuf[7], gbuf[6]);
    + t+ j6 c/ J) N1 ^' s8 l
  192.                  count[1] = makeuint16(gbuf[9], gbuf[8]);
    ) r' H; D- \7 N) t' V# q3 N; s2 J8 c
  193.                  count[2] = makeuint16(gbuf[11], gbuf[10]);
    & t! ?# h8 Q" A8 K1 m4 O2 D  o) ^
  194.                  DeviceRangeStatusInternal = ((gbuf[0] & 0x78) >> 3);
    * V5 E! s6 w% ]* ~

  195. ) p' Q/ R, B: n' q' t
  196.                  printf("\r\n ambient count = %4d signal count = %4d distance = %4d status = %d ",count[0],count[1],count[2],DeviceRangeStatusInternal);
    0 L9 M: n& ]( _% ]5 t
  197. # M0 |0 ?" v, }% u6 |. |+ ]
  198.                 delay_ms(1000);
    8 _2 Q2 M0 p7 F" t' v$ q
  199.                  
    ! I0 ~5 F8 i3 n1 K& d
  200.         ! a8 E  ^! V3 D+ `: S
  201.         }4 S7 C  I/ s+ p0 ?* ?  ^3 q% Q0 W: C
  202. }7 }% i# u$ p7 U* ~0 G- h8 u
  203. 1 P# V: e$ r9 f( w: C5 @
复制代码
6 w/ C1 \! |9 L! Y7 \5 m/ a: F
————————————————
) B1 K$ x5 Z3 A+ g; e4 o2 o7 {( Y) X版权声明:TangPeng_HanMO
6 L/ d/ h) U: _9 o$ q* r. k6 J5 ~- Y6 R- `, D: G2 Z

6 K4 B$ T2 N3 g3 l
赞 收藏 评论0 发布时间:2022-12-7 16:03

举报

0个回答

所属标签

相似技术帖

官网相关资源

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