概述
LSM6DSV16X是一款高性能、低功耗的6軸IMU傳感器,集成了3軸加速度計和3軸陀螺儀。本文將詳細介紹如何配置和讀取LSM6DSV16X傳感器的FIFO數(shù)據(jù),包括初始化、配置以及數(shù)據(jù)處理的完整流程, 以實現(xiàn)數(shù)據(jù)的批量處理和傳輸,減少系統(tǒng)功耗,提高應用的響應速度和數(shù)據(jù)處理效率。
最近在弄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
- 恢復傳感器默認配置并設置必要的參數(shù)
- 配置FIFO模式和水印閾值
- 設置加速度計和陀螺儀的數(shù)據(jù)速率
- 連續(xù)讀取FIFO中的傳感器數(shù)據(jù)并解析輸出
LSM6DSV16X傳感器包含一個FIFO緩沖區(qū),能夠存儲不同類型的數(shù)據(jù),以節(jié)省系統(tǒng)功耗。主處理器不需要連續(xù)輪詢傳感器數(shù)據(jù),而是可以在需要時喚醒并從FIFO中讀取重要數(shù)據(jù) 。
FIFO緩沖區(qū)可以存儲以下類型的數(shù)據(jù):
● 陀螺儀數(shù)據(jù)
● 加速度計數(shù)據(jù)
● 外部傳感器數(shù)據(jù)(最多4個)
● 計步器數(shù)據(jù)
● 時間戳
● 溫度
● 機器學習核心(MLC)特征和過濾數(shù)據(jù)
● 低功耗傳感器融合算法輸出數(shù)據(jù)(如四元數(shù)、陀螺儀偏差、重力向量等)
生成STM32CUBEMX
用STM32CUBEMX生成例程,這里使用MCU為STM32H503CB。 配置時鐘樹,配置時鐘為250M。
串口配置
查看原理圖,PB6和PB7設置為開發(fā)板的串口。
配置串口。
IIC配置
配置IIC速度為1M。
CS和SA0設置
串口重定向
打開魔術棒,勾選MicroLIB
在main.c中,添加頭文件,若不添加會出現(xiàn) identifier "FILE" is undefined報錯。
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
函數(shù)聲明和串口重定向:
/* 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為獲取函數(shù)。
對應的獲取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為重置函數(shù)。
對應的驅動程序,如下所示。
/* Restore default configuration */
lsm6dsv16x_reset_set(&dev_ctx, LSM6DSV16X_RESTORE_CTRL_REGS);
do {
lsm6dsv16x_reset_get(&dev_ctx, &rst);
} while (rst != LSM6DSV16X_READY);
BDU設置
在很多傳感器中,數(shù)據(jù)通常被存儲在輸出寄存器中,這些寄存器分為兩部分:MSB和LSB。這兩部分共同表示一個完整的數(shù)據(jù)值。例如,在一個加速度計中,MSB和LSB可能共同表示一個加速度的測量值。
連續(xù)更新模式(BDU = ‘0’):在默認模式下,輸出寄存器的值會持續(xù)不斷地被更新。這意味著在你讀取MSB和LSB的時候,寄存器中的數(shù)據(jù)可能會因為新的測量數(shù)據(jù)而更新。這可能導致一個問題:當你讀取MSB時,如果寄存器更新了,接下來讀取的LSB可能就是新的測量值的一部分,而不是與MSB相對應的值。這樣,你得到的就是一個“拼湊”的數(shù)據(jù),它可能無法準確代表任何實際的測量時刻。
塊數(shù)據(jù)更新(BDU)模式(BDU = ‘1’):當激活BDU功能時,輸出寄存器中的內容不會在讀取MSB和LSB之間更新。這就意味著一旦開始讀取數(shù)據(jù)(無論是先讀MSB還是LSB),寄存器中的那一組數(shù)據(jù)就被“鎖定”,直到兩部分都被讀取完畢。這樣可以確保你讀取的MSB和LSB是同一測量時刻的數(shù)據(jù),避免了讀取到代表不同采樣時刻的數(shù)據(jù)。
簡而言之,BDU位的作用是確保在讀取數(shù)據(jù)時,輸出寄存器的內容保持穩(wěn)定,從而避免讀取到拼湊或錯誤的數(shù)據(jù)。這對于需要高精度和穩(wěn)定性的應用尤為重要。
可以向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)進行設置。
設置加速度和角速度的量程和速率可以使用如下函數(shù)。
/* 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中寫入的字節(jié)數(shù)大于或等于這個閾值時,水印標志位會被置高。
具體描述如下:
● 1 LSb = TAG (1 Byte) + 1 sensor (6 Bytes) written in FIFO:
○ 每個LSb表示一個TAG(1字節(jié))和一個傳感器的數(shù)據(jù)(6字節(jié))被寫入FIFO。
○ 因此,每個水印閾值單位對應的大小是7字節(jié)(1字節(jié)的TAG加上6字節(jié)的傳感器數(shù)據(jù))。
下面代碼設置了FIFO的水印閾值。當FIFO中存儲的數(shù)據(jù)達到該閾值時,傳感器會產(chǎn)生一個中斷信號,以通知主處理器讀取數(shù)據(jù)。水印值是未讀傳感器數(shù)據(jù)TAG和6個字節(jié)的數(shù)據(jù)樣本總數(shù)。
lsm6dsv16x_fifo_watermark_set(&dev_ctx, FIFO_WATERMARK);
在配置LSM6DSV16X傳感器的FIFO功能時,每個傳感器數(shù)據(jù)樣本的大小為6字節(jié)。這是因為加速度計和陀螺儀的每個數(shù)據(jù)樣本都包含三個軸向的數(shù)據(jù),每個軸向的數(shù)據(jù)用2字節(jié)表示。具體來說:
● 加速度計數(shù)據(jù):包含X、Y、Z三個軸向的數(shù)據(jù),每個軸向的數(shù)據(jù)大小為2字節(jié)。因此,加速度計的一個完整數(shù)據(jù)樣本大小為3軸 * 2字節(jié) = 6字節(jié)。
● 陀螺儀數(shù)據(jù):同樣包含X、Y、Z三個軸向的數(shù)據(jù),每個軸向的數(shù)據(jù)大小也是2字節(jié)。因此,陀螺儀的一個完整數(shù)據(jù)樣本大小也是3軸 * 2字節(jié) = 6字節(jié)。
#define FIFO_WATERMARK 64的定義是為了在FIFO中存儲64個樣本后觸發(fā)中斷。因為每個樣本大小為7字節(jié)(1字節(jié)的TAG和6字節(jié)的傳感器數(shù)據(jù)),所以當FIFO中存儲的數(shù)據(jù)達到448字節(jié)(64 * 7字節(jié))時,會觸發(fā)中斷通知主處理器讀取數(shù)據(jù)。
這可以通過以下公式計算:
水印閾值字節(jié)數(shù)=64×(1字節(jié)的TAG+6字節(jié)的傳感器數(shù)據(jù))=448字節(jié)
這個設置可以確保在適當?shù)臅r間間隔內讀取數(shù)據(jù),既避免了頻繁中斷帶來的開銷,又不會因為FIFO溢出而丟失數(shù)據(jù)。
設置速率
LSM6DSV16X傳感器的FIFO控制寄存器3(FIFO_CTRL3)的內容,該寄存器用于選擇陀螺儀和加速度計數(shù)據(jù)寫入FIFO的批處理數(shù)據(jù)速率(BDR,Batch Data Rate)。以下是詳細描述:
FIFO_CTRL3寄存器(地址09h),該寄存器包含兩個主要字段:
● BDR_GY_[3:0]:選擇陀螺儀數(shù)據(jù)的批處理速率。
● BDR_XL_[3:0]:選擇加速度計數(shù)據(jù)的批處理速率。
將加速度計的數(shù)據(jù)速率(Output Data Rate, ODR)設置為60Hz。這意味著加速度計的數(shù)據(jù)將以每秒60次的頻率批量寫入FIFO。
將陀螺儀的數(shù)據(jù)速率設置為15Hz。這意味著陀螺儀的數(shù)據(jù)將以每秒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滿時停止收集數(shù)據(jù))
010: 連續(xù)模式直到水印標志被設置為滿模式(FIFO水印標志設置為滿模式之前,連續(xù)模式)
011: 連續(xù)模式直到解除觸發(fā),之后為FIFO模式
100: 旁路到連續(xù)模式(旁路模式直到解除觸發(fā),之后為連續(xù)模式)
101: 保留
110: 連續(xù)模式(如果FIFO滿了,新樣本將覆蓋舊的樣本)
111: 旁路到FIFO模式(旁路模式直到解除觸發(fā),之后為FIFO模式)
使用流模式有以下優(yōu)點:
持續(xù)數(shù)據(jù)采集:適用于需要連續(xù)監(jiān)控的場景,如運動跟蹤和實時監(jiān)控應用。
數(shù)據(jù)最新性:始終獲取到最新的數(shù)據(jù),避免數(shù)據(jù)滯后。
無需等待FIFO清空:當FIFO填滿時,新數(shù)據(jù)自動覆蓋舊數(shù)據(jù),無需手動清空FIFO。
/* Set FIFO mode to Stream mode (aka Continuous Mode) */
lsm6dsv16x_fifo_mode_set(&dev_ctx, LSM6DSV16X_STREAM_MODE);
設置FIFO時間戳批處理速率
LSM6DSV16X傳感器的時間戳批處理速率、溫度數(shù)據(jù)批處理速率、增強的EIS陀螺儀輸出批處理,以及FIFO的工作模式。這些配置確保傳感器數(shù)據(jù)能夠以適當?shù)乃俾屎湍J竭M行批處理和存儲,以滿足不同的應用需求。
/* 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可以使能時間戳計數(shù)器。計數(shù)器的值可以從TIMESTAMP0(40h),TIMESTAMP1(41h),TIMESTAMP2(42h)和TIMESTAMP3(43h)寄存器讀取。
lsm6dsv16x_timestamp_set(&dev_ctx, PROPERTY_ENABLE);
FIFO狀態(tài)寄存器
LSM6DSV16X傳感器的FIFO狀態(tài)寄存器FIFO_STATUS2 (1Ch)的FIFO_WTM_IA可以判斷FIFO水印狀態(tài)。
0:FIFO填充量低于水印。
1:FIFO填充量等于或大于水印。
DIFF_FIFO包括DIFF_FIFO_[7:0]和DIFF_FIFO_8,總共9位,用于精確表示未讀數(shù)據(jù)樣本的數(shù)量。
FIFO_DATA_OUT_TAG寄存器(地址78h)用于標識存儲在FIFO中的傳感器數(shù)據(jù)類型。以下是詳細解釋:
字段:
TAG_SENSOR_[4:0]:用于標識存儲在FIFO中的傳感器數(shù)據(jù)類型。
TAG_CNT_[1:0]:用于標識傳感器時間槽的2位計數(shù)器。
LSM6DSV16X傳感器的FIFO數(shù)據(jù)輸出寄存器用于讀取FIFO中的X軸、Y軸和Z軸數(shù)據(jù)。以下是詳細解釋:
FIFO_DATA_OUT_X_L (79h) 和 FIFO_DATA_OUT_X_H (7Ah) 寄存器
功能:讀取FIFO中X軸的數(shù)據(jù)。
寄存器描述:
FIFO_DATA_OUT_X_L (低字節(jié)):包含X軸數(shù)據(jù)的低8位。
FIFO_DATA_OUT_X_H (高字節(jié)):包含X軸數(shù)據(jù)的高8位。
組合讀取16位X軸數(shù)據(jù):D[15:0]。
FIFO_DATA_OUT_Y_L (7Bh) 和 FIFO_DATA_OUT_Y_H (7Ch) 寄存器
功能:讀取FIFO中Y軸的數(shù)據(jù)。
寄存器描述:
FIFO_DATA_OUT_Y_L (低字節(jié)):包含Y軸數(shù)據(jù)的低8位。
FIFO_DATA_OUT_Y_H (高字節(jié)):包含Y軸數(shù)據(jù)的高8位。
組合讀取16位Y軸數(shù)據(jù):D[15:0]。
FIFO_DATA_OUT_Z_L (7Dh) 和 FIFO_DATA_OUT_Z_H (7Eh) 寄存器
功能:讀取FIFO中Z軸的數(shù)據(jù)。
寄存器描述:
FIFO_DATA_OUT_Z_L (低字節(jié)):包含Z軸數(shù)據(jù)的低8位。
FIFO_DATA_OUT_Z_H (高字節(jié)):包含Z軸數(shù)據(jù)的高8位。
組合讀取16位Z軸數(shù)據(jù):D[15:0]。
其中時間戳速度單位為21.75us。
演示
實際測試如下所示,數(shù)據(jù)為64個數(shù)據(jù)。
加速度速率為60Hz,角速度速率為15Hz,所以數(shù)據(jù)輸出基本上為4個ACC數(shù)據(jù)一個GYR數(shù)據(jù)。
時間戳速率60Hz/8為7.5Hz(133.33ms),大概8個ACC數(shù)據(jù)之后出現(xiàn)一個時間戳數(shù)據(jù)。
下圖中的2個時間戳數(shù)據(jù)為81998618和81992474,81998618-81992474=6144*21.75us=133.632ms
審核編輯 黃宇
-
陀螺儀
+關注
關注
44文章
768瀏覽量
98193 -
fifo
+關注
關注
3文章
382瀏覽量
43404 -
AI
+關注
關注
87文章
28877瀏覽量
266254
發(fā)布評論請先 登錄
相關推薦
評論