1.簡介
在研究了各位大神的代碼后,結合購買模塊時商家提供的arduino的VL53L0X驅動,我修改ardiuno的驅動寫出了兼容C51的VL53L0X驅動。我的測試的單片機是STC8H3K64S4,IIC通信使用的時STC硬件的IIC。大家只需要把我的IIC驅動和顯示代碼修改成自己的,最后添加一個定時1ms的定時器作為VL53L0X的時基,就可以直接拿來用了。
這是本人第一次發帖,做的工作也比較簡單,如果有什么做的不好的還請諒解。
參考的網站:
http://www.zg4o1577.cn/bbs/dpj-167298-1.html
使用上面網站的代碼寫出來的程序,這個代碼只有最基本的測距功能,測距誤差大概在±5%。對我剛剛接觸VL53L0X時啟發很大。
在使用商家提供的arduino的VL53L0X驅動后,由于設置了VL53L0X的相關寄存器,精度可以達到±1%。當然超過模塊的1.2m的測距范圍精度還是會差很多。
2.上代碼
主函數 main.c
人機交互的相關代碼替換成自己的就行了
VL53L0X的驅動 VL53L0X.c
代碼太多了只顯示一部分,詳情看附件,大家用的時候記得添加時基就行了。
- // Most of the functionality of this library is based on the VL53L0X API
- // provided by ST (STSW-IMG005), and some of the explanatory comments are quoted
- // or paraphrased from the API source code, API user manual (UM2039), and the
- // VL53L0X datasheet.
- #include "inc/VL53L0X.h"
- #include "inc/VL53L0X_IIC.h"
- #include "NodeHandler.h"
- #include <string.h>
- unsigned char stop_variable;
- unsigned long measurement_timing_budget_us;
- unsigned int io_timeout = 0, timeout_start_ms, t2;
- bit did_timeout;
- //===================================
- //你自己的定時器時基定時1ms
- void Time2() interrupt 12
- {
- t2++;
- }
- //==================================================
- // Defines /////////////////////////////////////////////////////////////////////
- // The Arduino two-wire interface uses a 7-bit number for the address,
- // and sets the last bit correctly based on reads and writes
- #define ADDRESS_DEFAULT 0x52
- // Record the current time to check an upcoming timeout against
- #define startTimeout() (timeout_start_ms = t2)
- // Check if timeout is enabled (set to nonzero value) and has expired
- #define checkTimeoutExpired() (io_timeout > 0 && ((unsigned int)t2 - timeout_start_ms) > io_timeout)
- // Decode VCSEL (vertical cavity surface emitting laser) pulse period in PCLKs
- // from register value
- // based on VL53L0X_decode_vcsel_period()
- #define decodeVcselPeriod(reg_val) (((reg_val) + 1) << 1)
- // Encode VCSEL pulse period register value from period in PCLKs
- // based on VL53L0X_encode_vcsel_period()
- #define encodeVcselPeriod(period_pclks) (((period_pclks) >> 1) - 1)
復制代碼
IIC驅動
有人喜歡模擬IIC,有人喜歡硬件IIC,他們各有各的優點,大家按照自己的喜好替換調我的IIC驅動就行了
- #define VL53L0X_address 0x52
- //IIC寫8位數據
- void VL53L0X_Write(unsigned char address, unsigned char value)
- {
- P_SW2 = 0xB0;
- Start();
- SendData(VL53L0X_address);
- RecvACK();
- SendData(address);
- RecvACK();
- SendData(value);
- RecvACK();
- Stop();
- Delay();
- P_SW2 = 0x00;
- }
- //IIC寫16位數據
- void VL53L0X_Write16Bit(unsigned char address, unsigned int value)
- {
- P_SW2 = 0xB0;
- VL53L0X_Write(address++, (value >> 8) & 0xFF);
- VL53L0X_Write(address++, value & 0xFF);
- P_SW2 = 0x00;
- }
- //IIC寫32位數據
- //void VL53L0X_Write32Bit(unsigned char address, unsigned long value)
- //{
- // Start();
- // SendData(VL53L0X_address);
- // RecvACK();
- // SendData(address);
- // RecvACK();
- // SendData((value >> 24) & 0xFF);
- // RecvACK();
- // SendData((value >> 16) & 0xFF);
- // RecvACK();
- // SendData((value >> 8) & 0xFF);
- // RecvACK();
- // SendData(value & 0xFF);
- // RecvACK();
- // Stop();
- // Delay();
- //}
- //寫多位數據
- void VL53L0X_WriteMulti(unsigned char address, unsigned char const * src, unsigned char count)
- {
- P_SW2 = 0xB0;
- while(count--)
- {
- VL53L0X_Write(address++, *(src++));
- }
- P_SW2 = 0x00;
- }
- //IIC讀8位數據
- unsigned char VL53L0X_Read(unsigned char address)
- {
- unsigned char receive;
- P_SW2 = 0xB0;
- Start();
- SendData(VL53L0X_address);
- RecvACK();
- SendData(address);
- RecvACK();
-
- Start();
- SendData(VL53L0X_address + 1);
- RecvACK();
- receive = RecvData();
- SendNAK();
- Stop();
- Delay();
- P_SW2 = 0x00;
-
- return receive;
- }
- //IIC讀16位數據
- unsigned int VL53L0X_Read16Bit(unsigned char address)
- {
- unsigned int receive;
- P_SW2 = 0xB0;
- receive = VL53L0X_Read(address++) << 8;
- receive |= VL53L0X_Read(address);
- P_SW2 = 0x00;
-
- return receive;
- }
- //IIC讀多位數據
- void VL53L0X_ReadMulti(unsigned char address, unsigned char * dst, unsigned char count)
- {
- while(count--)
- {
- *(dst++) = VL53L0X_Read(address++);
- }
- P_SW2 = 0x00;
- }
復制代碼
3.其他
說一個我的IIC編程遇到的問題,我在IIC連續讀SDA的數據的時候會存在有時讀到的數據不穩定的情況
連續讀的時候,如下讀兩個字節
- //IIC讀16位數據
- unsigned int VL53L0X_Read16Bit(unsigned char address)
- {
- unsigned int receive;
- IICStart();
- IICSendData(VL53L0X_address);
- IICWaitACK();
- IICSendData(address);
- IICWaitACK();
- IICStop();
-
- IICStart();
- IICSendData(VL53L0X_address + 1);
- IICWaitACK();
復制代碼 VL53L0X的內部寄存器索引會在讀完一個寄存器后自加1,索引加1后讀下一個寄存器的數據。
那么如果這個自加1的索引自加的速度跟不上你IIC讀取的速度呢。
這樣IIC讀取的數據就會不可靠。
連續讀兩個字節,我修改成連續兩次讀一個字節后,數據的讀取就穩定許多了
- //IIC讀16位數據
- unsigned int VL53L0X_Read16Bit(unsigned char address)
- {
- unsigned int receive;
- P_SW2 = 0xB0;
- receive = VL53L0X_Read(address++) << 8; //兩個字節分兩次讀取
- receive |= VL53L0X_Read(address);
- P_SW2 = 0x00;
-
- return receive;
- }
復制代碼 或者大家有更好的見解也可以告訴我,畢竟我也是剛剛開始研究IIC,對IIC的認識也可能有錯誤(說不定我的程序就是建立在BUG上的 )
4.結果
5e9d23e805ecc0865f274ab32124379.jpg (185.72 KB, 下載次數: 27)
下載附件
2023-10-31 20:56 上傳
屏幕截圖(313).png (161.48 KB, 下載次數: 33)
下載附件
2023-10-31 20:57 上傳
5.工程源碼及附件
MRC048A-GY-VL53L0XV2 資料.rar
(696.82 KB, 下載次數: 5)
2023-10-31 20:18 上傳
點擊文件名下載附件
商家提供代碼 下載積分: 黑幣 -5
VL53L0X -硬件IIC(發帖).rar
(210.5 KB, 下載次數: 5)
2023-10-31 21:00 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|