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

STM32F103+VL53L0测距(一)

[复制链接]
STMCU小助手 发布时间:2022-12-7 16:03
本文记录了我使用STM32F103结合VL53L0测距模块的一个学习过程。  p% v/ M- ]8 t' J( v) }' t$ l
VL53L0是由ST公司最新推出的一款飞行时间测距+手势检测的微型模块,它应用非常广泛包括:激光测距、避障检测、一维手势识别等;接下来我们重点介绍它的激光测距功能。
2 m6 ^4 {( R4 T: Y
6 r- a. B0 S( H
一、模块的硬件连接

( ]1 n3 M( {! Q8 p7 ?1 J
3 f- X' I3 U  x" ~1 D2 r
20191215095427730.jpg
! F% r3 B2 [/ |1 D" m 20191215095607206.jpg
9 g! S* y& X" E/ t7 I/ N
; w+ {0 u% }+ f/ S1 {1 z. d% V上图便是我所使用的测距模块GYVL53L0XV2,它预留了六个接口:
/ b! R/ r# q6 _2 M1、VIN:供电电压,可在3V~5V范围内进行供电,但如果自己进行电路搭建的话,则需要一个线性稳压电路,将输入电压稳定在2.8V进行芯片供电和芯片I/O端口的上拉,这个可以自己看它的数据手册;
5 {$ f$ k% ~' G  Y$ h3 `+ ?2 t7 t2、GND:参考地;0 T1 J6 X& t5 e
3、SCL:I2C通信的时钟线;
" i8 \: Z! o* h% U4、SDA:I2C通信的数据线;! c; ^. p% C5 d1 v% a6 \# ~
5、XSHUT:芯片的使能管脚,电平1代表有效,电平0代表无效;% z6 k& K7 V" d" x# ~
6、GPIO1:芯片的中断管脚。
& J4 i! b# K9 g1 g4 L" y
6 ^* }/ {( w0 y+ n" |3 S2 {
本文与STM32F103的连线如下:. Y& C* d0 g6 Q9 j2 l+ O6 h- V: q* S
VIN--------------->3.3V
  }0 Y/ M: e- L% s" [8 BGND------------->GND
5 }  b, U& q  f( iSCL-------------->PB6! j/ q. L) v% h7 b2 Q; B! A8 Q
SDA-------------->PB7; ]- g* ]& }' N. u
+ m7 d% y; T3 Z8 {5 W0 Y; [" l
其中XSHUT与GPIO1没有连接,由电路可知,未连接时它们均上拉为高电平,XSHUT一直为高则代表芯片始终有效工作,如果有需要也可以进行连接,用单片机控制。在这里我没有使用到,因此直接不连接就行。
" H) P; i) g6 l5 r. h
6 g! ?. ^7 j' v+ [% t3 U

% c7 l, h$ y+ s: r" Y, K3 e二、程序代码
. e- q1 F8 o# @
  1. #ifndef _VL53L0_H
    9 A2 l3 `) G# }1 {0 S2 R$ }
  2. #define _VL53L0_H5 N5 e# F# V7 {9 x/ K. z6 c1 O1 K

  3. 0 V3 Y' h" a) ]" W
  4. #define VL53L0X_REG_IDENTIFICATION_MODEL_ID         0xc0
    ; d; Q! [: |  u1 Q( D! r1 Z
  5. #define VL53L0X_REG_IDENTIFICATION_REVISION_ID      0xc2' j2 d9 |, T5 b+ M
  6. #define VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD   0x50, W+ @! ~) L5 L' d+ x: o) u
  7. #define VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD 0x70' w' c" t7 Q+ }$ O- a# o1 v5 ]
  8. #define VL53L0X_REG_SYSRANGE_START                  0x00
    1 U% Q8 @8 s9 X: q7 E; p
  9. #define VL53L0X_REG_RESULT_INTERRUPT_STATUS         0x13! y1 o' c9 M2 K  R6 ~
  10. #define VL53L0X_REG_RESULT_RANGE_STATUS             0x146 s8 S" p; C& l( \
  11. #define VL53L0X_Add 0x29# `0 j& [- J$ c- o# \( p
  12. #include "stm32f10x.h"
    1 k; A$ Y  p; G' m) `; w% Y
  13. #include "bsp_usart1.h"
    ! b9 ~5 V+ X4 p$ B: Z
  14. #include "bsp_i2c_gpio.h"
    5 S( q+ e: f+ [
  15. 6 t+ v4 h  s4 @, z) ^
  16. u8 VL53L0X_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf);; L1 q( z& _& T! q* R: s  g
  17. u8 VL53L0X_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf);# v, v# J( ?% D2 M/ H* r* M
  18. u8 VL53L0X_Write_Byte(u8 reg,u8 data);
    : `  b( {* f  q; T
  19. u8 VL53L0X_Read_Byte(u8 reg);
    / d9 e8 D7 p5 m, C$ |
  20. uint16_t bswap(u8 b[]);                                  
    4 w% ?$ F/ v7 L! o; f. s
  21. uint16_t VL53L0X_decode_vcsel_period(short vcsel_period_reg);        & I7 z, X  ]* }4 L' i
  22. uint16_t makeuint16(int lsb, int msb);                 
    3 _0 {9 g' a. u4 L
  23. " u- m! x7 z: ~7 g
  24. #endif( e- v9 p! s+ ?; g( \5 o" _' P

  25. 9 A( d5 J/ W, a. V' I- C# n% ~
  26. #include "VL53L0.h"
    & C/ U6 v" @" D0 k2 L4 G
  27. uint16_t bswap(u8 b[])
    ; _7 _6 J7 ]4 i/ F+ f  B6 z
  28. {0 J' |7 [9 P! s2 E1 w. a7 H' y* K5 A
  29.         uint16_t val = ((b[0]<< 8) & b[1]);
    ( e7 }' I6 T6 a/ h$ h
  30.         return val;7 z6 \1 t: W8 N1 H! P& @3 {
  31. }
    8 L( c) Y2 T3 B/ a  t
  32. $ r9 [5 U) v4 S& t
  33. uint16_t VL53L0X_decode_vcsel_period(short vcsel_period_reg)
    1 v' X, o0 D' v0 _
  34. {
    : u4 d; o) G! L) r7 o
  35.         uint16_t vcsel_period_pclks = (vcsel_period_reg + 1) <<1;* ?7 q# Y$ E& z  H# M2 s: g( X
  36.         return vcsel_period_pclks;9 p  I) a- t6 ~/ F) M4 t
  37. }1 p, u. `$ G# L' J5 ]5 J

  38. , G- X( P2 ^9 L/ T5 V
  39. uint16_t makeuint16(int lsb, int msb)& _2 O" ^) H6 Y/ C# D; n
  40. {
    4 u6 o3 C# ^0 P( p4 u" H
  41.     return ((msb & 0xFF) << 8) | (lsb & 0xFF);% A8 {5 F/ O  {+ R# y) d
  42. }' D' j" R- y/ K/ u

  43. 9 i! [, \9 f( o2 R0 g$ _
  44. u8 VL53L0X_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf)' _7 Y8 J7 ?( s- k  }. G: ?7 |; y9 d
  45. {" M) p1 {( M9 i( z7 u
  46.         u8 i;
    # c# t6 P4 l& ^! w; p
  47.     i2c_Start(); 1 j: v/ {7 W- a7 b4 ^6 w
  48.         i2c_SendByte((addr<<1)|0);2 x& P8 s/ G7 v3 I" h3 M8 B# o) u
  49.         if(i2c_WaitAck())
    " C0 W( s$ H7 J# |6 d! u' z
  50.         {
    ( ]. ?) a1 r( Q* J# H
  51.                 i2c_Stop();                 
    ; ]" f: Z) Y% q1 u
  52.                 return 1;               
    + ?; ]0 [% Y/ `; r2 G8 |: @  [. R
  53.         }4 ^* r' Y2 }; S8 _) y% m
  54.     i2c_SendByte(reg);, r4 ]: I, ]& U! P& E
  55.     i2c_WaitAck();               
    3 @5 d) ]0 a# ~' r
  56.         for(i=0;i<len;i++)
    . k% t* I6 \- V
  57.         {
    * i+ N2 p# @$ G4 |
  58.                 i2c_SendByte(buf[i]);       
    $ |3 Y; `3 P9 H: }: E' ~' i4 n
  59.                 if(i2c_WaitAck())               
    $ _% ~7 ^4 Z# u' y! {
  60.                 {
    # P% K: b7 f/ E: y- Q- n6 M  I
  61.                         i2c_Stop();         ( j/ }1 b  [0 M/ r) S# Z8 `
  62.                         return 1;                 
    ) ]/ Q. M$ [' u. \8 J& b  \
  63.                 }                $ K4 B: l3 [# d
  64.         }    6 @. @6 `0 P' c
  65.     i2c_Stop();         ; X, l7 H6 g. T& a
  66.         return 0;       
    6 w; S+ c4 O. ^; |! M
  67. } 0 n. }2 [3 L' ]6 B# i- V
  68.   G# N6 O  `4 b6 S- n( P! C- x/ F# U
  69. u8 VL53L0X_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)' [# o' z9 F5 }$ v# Q1 ^5 f
  70. {
    / \- |& ^% J. l) r
  71.         i2c_Start();
    ; G" `" J7 {1 O9 k1 r4 p9 f
  72.         i2c_SendByte((addr<<1)|0);
    % q6 q7 g- Q2 F) ~. p/ [4 x& z7 ~- b7 l
  73.         if(i2c_WaitAck())        . @4 s5 e7 y+ |) K: l
  74.                 i2c_Stop();                 
    * r+ u' k3 @) k" D
  75.                 return 1;                0 x, b* T. b( b" k
  76.         }6 E4 `5 k9 |$ }( U0 `
  77.     i2c_SendByte(reg);        # m$ M6 O0 E: }6 D
  78.     i2c_WaitAck();               
    , V0 B4 ?) S* ], P3 B
  79.     i2c_Start();
    * b, ?6 q5 Q9 I4 b1 M
  80.         i2c_SendByte((addr<<1)|1);       
    8 U3 G) y1 B' b) d1 [. T
  81.     i2c_WaitAck();                1 Q; l5 h1 k4 p# ~! e9 P" H
  82.                
    : g! b$ y. o8 S1 a/ m; y7 o
  83. while(len)
    ; L* p, k( k2 w9 i. A' E" D: {+ n
  84.         {
    & ]' q  n5 e2 _/ N, p. W# P" Z
  85.                 if(len==1): k5 M3 m* j5 ]4 n: T% n) J
  86.                 {, C/ m0 x8 |! D, s
  87.                         *buf=i2c_ReadByte();
      x7 s5 V. k* e* Z
  88.                         i2c_NAck();* h/ g7 |0 `( y) T
  89.                 }
    / [/ m, l- N/ L
  90.                 else
    9 U6 q* U1 h1 y  t
  91.                 {5 w2 n3 V9 c, [, B- k, q# Q) H
  92.                         *buf=i2c_ReadByte();       
    0 ]+ v% E+ R) ^7 w
  93.                         i2c_Ack();
    4 Q- h4 X5 ?  [; L& Y& [
  94.                 }
    9 j" f( l7 B. J: h# e2 l0 \4 k
  95.                 len--;
    8 P+ c, y" A7 `* P8 ~6 r
  96.                 buf++;
    7 K' J% w. I' f# U
  97.         }    4 e" B& S9 t0 E  P. S" W
  98.     i2c_Stop();( W$ b; }; L' S2 v. T, N
  99.         return 0;        * b# V1 E# s& `
  100. }! O; l  P4 l# `  f0 J$ m" c' `

  101. , E) M% i% c$ s# H3 h) o  s1 G
  102. //IIC写一个字节
    ) w! j7 c' k: H0 W; y
  103. //reg:寄存器地址( l) ~+ l, f6 d% V. E
  104. //data:数据8 ?( {, p0 o* U. S/ z/ a& d% H
  105. //·返回值:0,代表正常
    7 K. G1 y& {" w5 S, I
  106. //     其他,错误代码& |. d. c7 {+ s9 [: [8 B- {
  107. u8 VL53L0X_Write_Byte(u8 reg,u8 data)                                  6 ~' [& m* A' _
  108. { 9 [0 A: |, z! l6 A# k
  109.     i2c_Start(); 4 e$ b8 P0 B  K
  110.         i2c_SendByte((VL53L0X_Add<<1)|0);//发送器件地址+写命令
    % ^( o+ h% I8 }% r1 k9 o6 i9 L- o
  111.         if(i2c_WaitAck())        //等待应答, j$ I) h; \& g2 Z% M# A
  112.         {- ~$ V' A) A) g. y7 `+ ^$ R" y* V( h
  113.                 i2c_Stop();                 
    6 ^% H' u7 c" W" f$ M0 K& e" @
  114.                 return 1;                2 g1 a5 ]! M/ r2 q. _
  115.         }
    0 q; c3 P! G, h) p* M' R1 a( F
  116.     i2c_SendByte(reg);        //写寄存器地址1 }- ~! e. g5 V8 k
  117.     i2c_WaitAck();                //等待应答
    9 M. w4 W- |9 V
  118.         i2c_SendByte(data);//发送数据
    9 _4 y8 t+ g* u. C! a' d, B7 n
  119.         if(i2c_WaitAck())        //等待应答3 x% H# L: a9 O: o* a: d
  120.         {" a: e. y# q. o- S
  121.                 i2c_Stop();         ; I) o! e! F' i3 l4 G' I/ `9 \0 _; M
  122.                 return 1;                 
    6 A7 f/ P& g+ X) E( h7 Q
  123.         }                 ) Y6 O' V9 Q: A7 u0 \. E- b& c
  124.     i2c_Stop();         
    $ U' ~. d% M9 P. b" \4 U
  125.         return 0;: C( n' N; L- S8 m1 R1 ^4 z' P: Y, c
  126. }
    7 t6 X8 c* Z, ?, F5 T! e
  127. //IIC读一个字节6 ]6 C/ f. f! `
  128. //reg:寄存器地址. U( _/ [  M7 z3 }! `; y
  129. //返回值:读到的数据
    . F% I5 S) q$ T+ p
  130. u8 VL53L0X_Read_Byte(u8 reg)) `6 o: t! ]; [0 g
  131. {0 S6 c; L- I* A/ U0 }: z
  132.         u8 res;4 d9 q( h5 N7 Z0 X7 Q
  133.     i2c_Start(); 3 o# h) P( M1 Q; T; O$ ]* L
  134.         i2c_SendByte(0x52);//发送器件地址+写命令        * W" F: [" ]( |; a+ F
  135.         i2c_WaitAck();                //等待应答6 e% Q2 X& m9 \) ?9 h
  136.     i2c_SendByte(reg);        //写寄存器地址
    1 J1 f% t8 H" U; E. U+ [% I
  137.     i2c_WaitAck();                //等待应答
    9 n. t% k  l6 V# M  ~
  138.     i2c_Start();
    % ]( m8 r1 J+ R( i$ w
  139.         i2c_SendByte(0x53 );//发送器件地址+读命令/ f9 y; d7 t  x+ ?2 }2 Q
  140.     i2c_WaitAck();
    - K1 o2 u$ J' t
  141. i2c_SendByte(reg);    //写寄存器地址
    4 Q" q% ^! a2 s' Y- Y
  142.         res=i2c_ReadByte();   //读取数据,发送nACK
    ( `+ T* A1 r+ c$ P
  143.     i2c_Stop();                        //产生一个停止条件2 b' H8 C; G$ w5 C* L: W4 j8 @$ B
  144.         return res;               
    , d! s. ^, t( z2 C; n' |5 C
  145. }
    $ g$ r+ C+ G& ~' C/ J
  146. % D" c) J* O  V7 M
  147. main.c:
    4 g! f8 }) x) i' b4 y, M
  148. #include "stm32f10x.h"8 L2 [5 I( x: x3 {+ v( y
  149. #include "bsp_usart1.h"+ u- g1 ?- f" I. O: U1 T2 _
  150. #include "bsp_i2c_gpio.h"
    : k* a5 f4 _7 R4 J6 P; T2 }
  151. #include "VL53L0.h"# c! M* F3 ?* f& @+ J
  152. # I' C" l- b# g% ^4 m! ~
  153. uint8_t Rxflag=0;
    / K# b% p% V: ^: W  u
  154. uint8_t ucTemp;# ?! s  H- F5 F% M+ |# J3 l% v( A, ~9 F

  155. ; l: \# M0 ?) ^* j, L# l
  156. int main(void)* D, e& w+ x, [
  157. {       
    , m# e: m; q4 ~/ S, Y
  158.        
    , Z1 \. v& Q* j, i7 D5 J
  159.         u8 val = 0;
    4 z- G# q9 Q5 p2 K: x& X
  160.   u8 gbuf[16];
    " Z8 B4 [! ~+ P- F) L  \
  161.         u8 DeviceRangeStatusInternal;
    % s% P+ V! V4 K: Y) h
  162.         u8 tp=0;
    ; ?- f7 j4 z- m5 e: F2 f; H! S
  163.        
    ( R. B. e+ r4 w. ~+ ^) ^  h# ^
  164.         uint32_t cnt = 0;8 {( Y& F; o. D. H
  165.         uint16_t count[3];) ]! l  K# c- g9 w
  166.         + B7 {5 X7 `) @* L/ p: q& H) }
  167.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    : S/ |6 z2 h6 f( h+ v
  168.         USARTx_Config();/ f* Z/ q+ K9 q* E6 x  H/ \- P4 G
  169.         NVIC_Configuration();8 H3 M2 ^# s/ Y  c+ e' ]; t$ c
  170.         InitSysTick();+ `' k0 f# S8 P2 j, g
  171.          bsp_InitI2C();
    ; \5 D5 i, g! c3 p7 b  f; M3 N
  172.         while(1)4 i5 Z$ ~3 a# d1 x0 |
  173.         {7 e9 F2 F+ b4 l# r; K6 F7 N
  174.         5 Z# d% u% J% m4 v
  175.           VL53L0X_Write_Byte(VL53L0X_REG_SYSRANGE_START, 0x01);
    8 {* V& Z  D; n$ c. |& a
  176.           1 |* v0 u0 e8 A: Z& t4 g0 P
  177.                  while(cnt < 100)( W; @$ A5 W' ?6 ^
  178.                  {
    3 ?+ c! W2 i. B3 \) `9 ]) [$ o
  179.                                 delay_ms(10);) C9 [  O$ ^1 q- R" Q' z
  180.                                 val = VL53L0X_Read_Byte(VL53L0X_REG_RESULT_RANGE_STATUS);0 s2 }0 R4 f) Y& F8 q7 Z) i* t2 k
  181.                                 if( val & 0x01) break;
    7 C- G( p7 m! v/ h
  182.                                 cnt++;
    4 O5 C: k7 s/ i4 h
  183.                  }
    0 S' y4 G! Y. M5 t* s6 S9 R8 U( d

  184. 2 k- q8 ]7 o7 ]7 c8 Z" d, ]- x
  185.                  if( val & 0x01)/ X6 s4 K4 Z+ T' ?, f- S; O# K1 d
  186.                                 printf("\r\n readey \r\n");
    # d; X: x9 J/ \' Z
  187.                  else6 R; C- R) h  f; j8 X, L3 H
  188.                                 printf("\r\n not readey \r\n");
    " u. @$ ~" o9 S3 n/ Z
  189.      VL53L0X_Read_Len(VL53L0X_Add, 0x14 , 12, gbuf);
    3 r6 G6 x: x3 J1 }2 k7 O* B& ^
  190.                         6 |" m$ w2 Q2 y: m
  191.                  count[0] = makeuint16(gbuf[7], gbuf[6]);
    & d( [  B5 f9 ~
  192.                  count[1] = makeuint16(gbuf[9], gbuf[8]);
    2 X. r+ R5 \. H5 ~5 p' O* }
  193.                  count[2] = makeuint16(gbuf[11], gbuf[10]);# f, j2 @# X6 n) ?6 T* c8 j
  194.                  DeviceRangeStatusInternal = ((gbuf[0] & 0x78) >> 3);
    : |5 B: u; L4 |/ F3 }8 T

  195. - {. m/ ~9 z/ P4 q
  196.                  printf("\r\n ambient count = %4d signal count = %4d distance = %4d status = %d ",count[0],count[1],count[2],DeviceRangeStatusInternal);  k2 @& l8 E9 x* F& t) y
  197. 8 G* S4 t* j# B* V' Z& P6 ~/ T
  198.                 delay_ms(1000);7 B, X; D/ O- B3 g" S3 e
  199.                  . P( m3 \; A) N  [; Q2 w7 a/ e
  200.        
    / l+ g# O# f4 ~) [4 u
  201.         }+ \$ }$ y9 Y9 H$ z$ M
  202. }
    ) z& m% {" Y8 t9 x- Q( o
  203. % w' g  @5 q# E% O% J
复制代码

; c& R* k  W; X  |1 @$ V4 D- g————————————————6 r0 z1 u/ i* q% W
版权声明:TangPeng_HanMO" _- I* i# B4 j/ u0 \& @
5 N! @% E# D0 y
7 \" q# {1 L0 a* R( J$ i
收藏 评论0 发布时间:2022-12-7 16:03

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版