概述
LSM6DSV16X是一款高性能、低功耗的6軸IMU傳感器,集成了3軸加速度計和3軸陀螺儀。本文將詳細介紹如何配置和讀取LSM6DSV16X傳感器的FIFO數據,包括初始化、配置以及數據處理的完整流程, 以實現數據的批量處理和傳輸,減少系統功耗,提高應用的響應速度和數據處理效率。
最近在弄ST和瑞薩RA的課程,需要樣片的可以加群申請:615061293 。
視頻教學
[https://www.bilibili.com/video/BV12s421T73k/]
樣品申請
[https://www.wjx.top/vm/OhcKxJk.aspx#]
源碼下載
[https://download.csdn.net/download/qq_24312945/89471311]
主要內容
- 初始化LSM6DSV16X傳感器并檢查其設備ID
- 恢復傳感器默認配置并設置必要的參數
- 配置FIFO模式和水印閾值
- 設置加速度計和陀螺儀的數據速率
- 連續讀取FIFO中的傳感器數據并解析輸出
LSM6DSV16X傳感器包含一個FIFO緩沖區,能夠存儲不同類型的數據,以節省系統功耗。主處理器不需要連續輪詢傳感器數據,而是可以在需要時喚醒并從FIFO中讀取重要數據 。
FIFO緩沖區可以存儲以下類型的數據:
● 陀螺儀數據
● 加速度計數據
● 外部傳感器數據(最多4個)
● 計步器數據
● 時間戳
● 溫度
● 機器學習核心(MLC)特征和過濾數據
● 低功耗傳感器融合算法輸出數據(如四元數、陀螺儀偏差、重力向量等)
生成STM32CUBEMX
用STM32CUBEMX生成例程,這里使用MCU為STM32H503CB。 配置時鐘樹,配置時鐘為250M。
串口配置
查看原理圖,PB6和PB7設置為開發板的串口。
配置串口。
IIC配置
配置IIC速度為1M。
CS和SA0設置
串口重定向
打開魔術棒,勾選MicroLIB
在main.c中,添加頭文件,若不添加會出現 identifier "FILE" is undefined報錯。
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
函數聲明和串口重定向:
/* USER CODE BEGIN PFP */
int fputc(int ch, FILE *f){
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch
}
/* USER CODE END PFP */
參考程序
[https://github.com/STMicroelectronics/lsm6dsv16x-pid/tree/main](
初始換管腳
由于需要向LSM6DSV16X_I2C_ADD_L寫入以及為IIC模式。
所以使能CS為高電平,配置為IIC模式。 配置SA0為高電平。
printf("HELLO!n");
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(SA0_GPIO_Port, SA0_Pin, GPIO_PIN_RESET);
HAL_Delay(100);
lsm6dsv16x_fifo_status_t fifo_status;
stmdev_ctx_t dev_ctx;
lsm6dsv16x_reset_t rst;
/* Initialize mems driver interface */
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;
dev_ctx.mdelay = platform_delay;
dev_ctx.handle = &SENSOR_BUS;
/* Init test platform */
// platform_init(dev_ctx.handle);
/* Wait sensor boot time */
platform_delay(BOOT_TIME);
獲取ID
可以向WHO_AM_I (0Fh)獲取固定值,判斷是否為0x70。
lsm6dsv16x_device_id_get為獲取函數。
對應的獲取ID驅動程序,如下所示。
/* Check device ID */
lsm6dsv16x_device_id_get(&dev_ctx, &whoamI);
printf("LSM6DSV16X_ID=0x%x,whoamI=0x%x",LSM6DSV16X_ID,whoamI);
if (whoamI != LSM6DSV16X_ID)
while (1);
復位操作
可以向CTRL3 (12h)的SW_RESET寄存器寫入1進行復位。
lsm6dsv16x_reset_set為重置函數。
對應的驅動程序,如下所示。
/* Restore default configuration */
lsm6dsv16x_reset_set(&dev_ctx, LSM6DSV16X_RESTORE_CTRL_REGS);
do {
lsm6dsv16x_reset_get(&dev_ctx, &rst);
} while (rst != LSM6DSV16X_READY);
BDU設置
在很多傳感器中,數據通常被存儲在輸出寄存器中,這些寄存器分為兩部分:MSB和LSB。這兩部分共同表示一個完整的數據值。例如,在一個加速度計中,MSB和LSB可能共同表示一個加速度的測量值。
連續更新模式(BDU = ‘0’):在默認模式下,輸出寄存器的值會持續不斷地被更新。這意味著在你讀取MSB和LSB的時候,寄存器中的數據可能會因為新的測量數據而更新。這可能導致一個問題:當你讀取MSB時,如果寄存器更新了,接下來讀取的LSB可能就是新的測量值的一部分,而不是與MSB相對應的值。這樣,你得到的就是一個“拼湊”的數據,它可能無法準確代表任何實際的測量時刻。
塊數據更新(BDU)模式(BDU = ‘1’):當激活BDU功能時,輸出寄存器中的內容不會在讀取MSB和LSB之間更新。這就意味著一旦開始讀取數據(無論是先讀MSB還是LSB),寄存器中的那一組數據就被“鎖定”,直到兩部分都被讀取完畢。這樣可以確保你讀取的MSB和LSB是同一測量時刻的數據,避免了讀取到代表不同采樣時刻的數據。
簡而言之,BDU位的作用是確保在讀取數據時,輸出寄存器的內容保持穩定,從而避免讀取到拼湊或錯誤的數據。這對于需要高精度和穩定性的應用尤為重要。
可以向CTRL3 (12h)的BDU寄存器寫入1進行開啟。
對應的驅動程序,如下所示。
/* Enable Block Data Update */
lsm6dsv16x_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
設置量程
速率可以通過CTRL1 (10h)設置加速度速率和CTRL2 (11h)進行設置角速度速率。
設置加速度量程可以通過CTRL8 (17h)進行設置。 設置角速度量程可以通過CTRL6 (15h)進行設置。
設置加速度和角速度的量程和速率可以使用如下函數。
/* Set full scale */
lsm6dsv16x_xl_full_scale_set(&dev_ctx, LSM6DSV16X_2g);
lsm6dsv16x_gy_full_scale_set(&dev_ctx, LSM6DSV16X_2000dps);
設置FIFO水印
FIFO控制寄存器1 (FIFO_CTRL1):這個寄存器用于設置FIFO的水印閾值。
● WTM_[7:0]:FIFO水印閾值。當FIFO中寫入的字節數大于或等于這個閾值時,水印標志位會被置高。
具體描述如下:
● 1 LSb = TAG (1 Byte) + 1 sensor (6 Bytes) written in FIFO:
○ 每個LSb表示一個TAG(1字節)和一個傳感器的數據(6字節)被寫入FIFO。
○ 因此,每個水印閾值單位對應的大小是7字節(1字節的TAG加上6字節的傳感器數據)。
下面代碼設置了FIFO的水印閾值。當FIFO中存儲的數據達到該閾值時,傳感器會產生一個中斷信號,以通知主處理器讀取數據。水印值是未讀傳感器數據TAG和6個字節的數據樣本總數。
lsm6dsv16x_fifo_watermark_set(&dev_ctx, FIFO_WATERMARK);
在配置LSM6DSV16X傳感器的FIFO功能時,每個傳感器數據樣本的大小為6字節。這是因為加速度計和陀螺儀的每個數據樣本都包含三個軸向的數據,每個軸向的數據用2字節表示。具體來說:
● 加速度計數據:包含X、Y、Z三個軸向的數據,每個軸向的數據大小為2字節。因此,加速度計的一個完整數據樣本大小為3軸 * 2字節 = 6字節。
● 陀螺儀數據:同樣包含X、Y、Z三個軸向的數據,每個軸向的數據大小也是2字節。因此,陀螺儀的一個完整數據樣本大小也是3軸 * 2字節 = 6字節。
#define FIFO_WATERMARK 64的定義是為了在FIFO中存儲64個樣本后觸發中斷。因為每個樣本大小為7字節(1字節的TAG和6字節的傳感器數據),所以當FIFO中存儲的數據達到448字節(64 * 7字節)時,會觸發中斷通知主處理器讀取數據。
這可以通過以下公式計算:
水印閾值字節數=64×(1字節的TAG+6字節的傳感器數據)=448字節
這個設置可以確保在適當的時間間隔內讀取數據,既避免了頻繁中斷帶來的開銷,又不會因為FIFO溢出而丟失數據。
設置速率
LSM6DSV16X傳感器的FIFO控制寄存器3(FIFO_CTRL3)的內容,該寄存器用于選擇陀螺儀和加速度計數據寫入FIFO的批處理數據速率(BDR,Batch Data Rate)。以下是詳細描述:
FIFO_CTRL3寄存器(地址09h),該寄存器包含兩個主要字段:
● BDR_GY_[3:0]:選擇陀螺儀數據的批處理速率。
● BDR_XL_[3:0]:選擇加速度計數據的批處理速率。
將加速度計的數據速率(Output Data Rate, ODR)設置為60Hz。這意味著加速度計的數據將以每秒60次的頻率批量寫入FIFO。
將陀螺儀的數據速率設置為15Hz。這意味著陀螺儀的數據將以每秒15次的頻率批量寫入FIFO。
/* Set FIFO batch XL/Gyro ODR to 12.5Hz */
lsm6dsv16x_fifo_xl_batch_set(&dev_ctx, LSM6DSV16X_XL_BATCHED_AT_60Hz);
lsm6dsv16x_fifo_gy_batch_set(&dev_ctx, LSM6DSV16X_GY_BATCHED_AT_15Hz);
使用流模式
FIFO控制寄存器4(FIFO_CTRL4)用于選擇FIFO模式,并提供以下選項:
FIFO_MODE_[2:0] 字段用于選擇FIFO模式,詳細描述如下:
000: 旁路模式(FIFO禁用,默認)
001: FIFO模式(當FIFO滿時停止收集數據)
010: 連續模式直到水印標志被設置為滿模式(FIFO水印標志設置為滿模式之前,連續模式)
011: 連續模式直到解除觸發,之后為FIFO模式
100: 旁路到連續模式(旁路模式直到解除觸發,之后為連續模式)
101: 保留
110: 連續模式(如果FIFO滿了,新樣本將覆蓋舊的樣本)
111: 旁路到FIFO模式(旁路模式直到解除觸發,之后為FIFO模式)
使用流模式有以下優點:
持續數據采集:適用于需要連續監控的場景,如運動跟蹤和實時監控應用。
數據最新性:始終獲取到最新的數據,避免數據滯后。
無需等待FIFO清空:當FIFO填滿時,新數據自動覆蓋舊數據,無需手動清空FIFO。
/* Set FIFO mode to Stream mode (aka Continuous Mode) */
lsm6dsv16x_fifo_mode_set(&dev_ctx, LSM6DSV16X_STREAM_MODE);
設置FIFO時間戳批處理速率
LSM6DSV16X傳感器的時間戳批處理速率、溫度數據批處理速率、增強的EIS陀螺儀輸出批處理,以及FIFO的工作模式。這些配置確保傳感器數據能夠以適當的速率和模式進行批處理和存儲,以滿足不同的應用需求。
/* Set Output Data Rate */
lsm6dsv16x_xl_data_rate_set(&dev_ctx, LSM6DSV16X_ODR_AT_60Hz);
lsm6dsv16x_gy_data_rate_set(&dev_ctx, LSM6DSV16X_ODR_AT_15Hz);
lsm6dsv16x_fifo_timestamp_batch_set(&dev_ctx, LSM6DSV16X_TMSTMP_DEC_8);
使能時間戳
FUNCTIONS_ENABLE寄存器(地址50h) 的TIMESTAMP_EN可以使能時間戳計數器。計數器的值可以從TIMESTAMP0(40h),TIMESTAMP1(41h),TIMESTAMP2(42h)和TIMESTAMP3(43h)寄存器讀取。
lsm6dsv16x_timestamp_set(&dev_ctx, PROPERTY_ENABLE);
FIFO狀態寄存器
LSM6DSV16X傳感器的FIFO狀態寄存器FIFO_STATUS2 (1Ch)的FIFO_WTM_IA可以判斷FIFO水印狀態。
0:FIFO填充量低于水印。
1:FIFO填充量等于或大于水印。
DIFF_FIFO包括DIFF_FIFO_[7:0]和DIFF_FIFO_8,總共9位,用于精確表示未讀數據樣本的數量。
FIFO_DATA_OUT_TAG寄存器(地址78h)用于標識存儲在FIFO中的傳感器數據類型。以下是詳細解釋:
字段:
TAG_SENSOR_[4:0]:用于標識存儲在FIFO中的傳感器數據類型。
TAG_CNT_[1:0]:用于標識傳感器時間槽的2位計數器。
LSM6DSV16X傳感器的FIFO數據輸出寄存器用于讀取FIFO中的X軸、Y軸和Z軸數據。以下是詳細解釋:
FIFO_DATA_OUT_X_L (79h) 和 FIFO_DATA_OUT_X_H (7Ah) 寄存器
功能:讀取FIFO中X軸的數據。
寄存器描述:
FIFO_DATA_OUT_X_L (低字節):包含X軸數據的低8位。
FIFO_DATA_OUT_X_H (高字節):包含X軸數據的高8位。
組合讀取16位X軸數據:D[15:0]。
FIFO_DATA_OUT_Y_L (7Bh) 和 FIFO_DATA_OUT_Y_H (7Ch) 寄存器
功能:讀取FIFO中Y軸的數據。
寄存器描述:
FIFO_DATA_OUT_Y_L (低字節):包含Y軸數據的低8位。
FIFO_DATA_OUT_Y_H (高字節):包含Y軸數據的高8位。
組合讀取16位Y軸數據:D[15:0]。
FIFO_DATA_OUT_Z_L (7Dh) 和 FIFO_DATA_OUT_Z_H (7Eh) 寄存器
功能:讀取FIFO中Z軸的數據。
寄存器描述:
FIFO_DATA_OUT_Z_L (低字節):包含Z軸數據的低8位。
FIFO_DATA_OUT_Z_H (高字節):包含Z軸數據的高8位。
組合讀取16位Z軸數據:D[15:0]。
其中時間戳速度單位為21.75us。
演示
實際測試如下所示,數據為64個數據。
加速度速率為60Hz,角速度速率為15Hz,所以數據輸出基本上為4個ACC數據一個GYR數據。
時間戳速率60Hz/8為7.5Hz(133.33ms),大概8個ACC數據之后出現一個時間戳數據。
下圖中的2個時間戳數據為81998618和81992474,81998618-81992474=6144*21.75us=133.632ms
審核編輯 黃宇
-
陀螺儀
+關注
關注
44文章
792瀏覽量
98978 -
fifo
+關注
關注
3文章
389瀏覽量
43858 -
AI
+關注
關注
87文章
31516瀏覽量
270333
發布評論請先 登錄
相關推薦
評論