概述
LSM6DSV16X是一款高性能、低功耗的6軸IMU傳感器,集成了3軸加速度計(jì)和3軸陀螺儀。本文將詳細(xì)介紹如何配置和讀取LSM6DSV16X傳感器的FIFO數(shù)據(jù),包括初始化、配置以及數(shù)據(jù)處理的完整流程, 以實(shí)現(xiàn)數(shù)據(jù)的批量處理和傳輸,減少系統(tǒng)功耗,提高應(yīng)用的響應(yīng)速度和數(shù)據(jù)處理效率。
最近在弄ST和瑞薩RA的課程,需要樣片的可以加群申請(qǐng):615061293 。
視頻教學(xué)
[https://www.bilibili.com/video/BV12s421T73k/]
樣品申請(qǐng)
[https://www.wjx.top/vm/OhcKxJk.aspx#]
源碼下載
[https://download.csdn.net/download/qq_24312945/89471311]
主要內(nèi)容
- 初始化LSM6DSV16X傳感器并檢查其設(shè)備ID
- 恢復(fù)傳感器默認(rèn)配置并設(shè)置必要的參數(shù)
- 配置FIFO模式和水印閾值
- 設(shè)置加速度計(jì)和陀螺儀的數(shù)據(jù)速率
- 連續(xù)讀取FIFO中的傳感器數(shù)據(jù)并解析輸出
LSM6DSV16X傳感器包含一個(gè)FIFO緩沖區(qū),能夠存儲(chǔ)不同類型的數(shù)據(jù),以節(jié)省系統(tǒng)功耗。主處理器不需要連續(xù)輪詢傳感器數(shù)據(jù),而是可以在需要時(shí)喚醒并從FIFO中讀取重要數(shù)據(jù) 。
FIFO緩沖區(qū)可以存儲(chǔ)以下類型的數(shù)據(jù):
● 陀螺儀數(shù)據(jù)
● 加速度計(jì)數(shù)據(jù)
● 外部傳感器數(shù)據(jù)(最多4個(gè))
● 計(jì)步器數(shù)據(jù)
● 時(shí)間戳
● 溫度
● 機(jī)器學(xué)習(xí)核心(MLC)特征和過濾數(shù)據(jù)
● 低功耗傳感器融合算法輸出數(shù)據(jù)(如四元數(shù)、陀螺儀偏差、重力向量等)
生成STM32CUBEMX
用STM32CUBEMX生成例程,這里使用MCU為STM32H503CB。 配置時(shí)鐘樹,配置時(shí)鐘為250M。
串口配置
查看原理圖,PB6和PB7設(shè)置為開發(fā)板的串口。
配置串口。
IIC配置
配置IIC速度為1M。
CS和SA0設(shè)置
串口重定向
打開魔術(shù)棒,勾選MicroLIB
在main.c中,添加頭文件,若不添加會(huì)出現(xiàn) identifier "FILE" is undefined報(bào)錯(cuò)。
/* 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ù)。
對(duì)應(yīng)的獲取ID驅(qū)動(dòng)程序,如下所示。
/* 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);
復(fù)位操作
可以向CTRL3 (12h)的SW_RESET寄存器寫入1進(jìn)行復(fù)位。
lsm6dsv16x_reset_set為重置函數(shù)。
對(duì)應(yīng)的驅(qū)動(dòng)程序,如下所示。
/* 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è)置
在很多傳感器中,數(shù)據(jù)通常被存儲(chǔ)在輸出寄存器中,這些寄存器分為兩部分:MSB和LSB。這兩部分共同表示一個(gè)完整的數(shù)據(jù)值。例如,在一個(gè)加速度計(jì)中,MSB和LSB可能共同表示一個(gè)加速度的測(cè)量值。
連續(xù)更新模式(BDU = ‘0’):在默認(rèn)模式下,輸出寄存器的值會(huì)持續(xù)不斷地被更新。這意味著在你讀取MSB和LSB的時(shí)候,寄存器中的數(shù)據(jù)可能會(huì)因?yàn)樾碌臏y(cè)量數(shù)據(jù)而更新。這可能導(dǎo)致一個(gè)問題:當(dāng)你讀取MSB時(shí),如果寄存器更新了,接下來讀取的LSB可能就是新的測(cè)量值的一部分,而不是與MSB相對(duì)應(yīng)的值。這樣,你得到的就是一個(gè)“拼湊”的數(shù)據(jù),它可能無法準(zhǔn)確代表任何實(shí)際的測(cè)量時(shí)刻。
塊數(shù)據(jù)更新(BDU)模式(BDU = ‘1’):當(dāng)激活BDU功能時(shí),輸出寄存器中的內(nèi)容不會(huì)在讀取MSB和LSB之間更新。這就意味著一旦開始讀取數(shù)據(jù)(無論是先讀MSB還是LSB),寄存器中的那一組數(shù)據(jù)就被“鎖定”,直到兩部分都被讀取完畢。這樣可以確保你讀取的MSB和LSB是同一測(cè)量時(shí)刻的數(shù)據(jù),避免了讀取到代表不同采樣時(shí)刻的數(shù)據(jù)。
簡而言之,BDU位的作用是確保在讀取數(shù)據(jù)時(shí),輸出寄存器的內(nèi)容保持穩(wěn)定,從而避免讀取到拼湊或錯(cuò)誤的數(shù)據(jù)。這對(duì)于需要高精度和穩(wěn)定性的應(yīng)用尤為重要。
可以向CTRL3 (12h)的BDU寄存器寫入1進(jìn)行開啟。
對(duì)應(yīng)的驅(qū)動(dòng)程序,如下所示。
/* Enable Block Data Update */
lsm6dsv16x_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
設(shè)置量程
速率可以通過CTRL1 (10h)設(shè)置加速度速率和CTRL2 (11h)進(jìn)行設(shè)置角速度速率。
設(shè)置加速度量程可以通過CTRL8 (17h)進(jìn)行設(shè)置。 設(shè)置角速度量程可以通過CTRL6 (15h)進(jìn)行設(shè)置。
設(shè)置加速度和角速度的量程和速率可以使用如下函數(shù)。
/* Set full scale */
lsm6dsv16x_xl_full_scale_set(&dev_ctx, LSM6DSV16X_2g);
lsm6dsv16x_gy_full_scale_set(&dev_ctx, LSM6DSV16X_2000dps);
設(shè)置FIFO水印
FIFO控制寄存器1 (FIFO_CTRL1):這個(gè)寄存器用于設(shè)置FIFO的水印閾值。
● WTM_[7:0]:FIFO水印閾值。當(dāng)FIFO中寫入的字節(jié)數(shù)大于或等于這個(gè)閾值時(shí),水印標(biāo)志位會(huì)被置高。
具體描述如下:
● 1 LSb = TAG (1 Byte) + 1 sensor (6 Bytes) written in FIFO:
○ 每個(gè)LSb表示一個(gè)TAG(1字節(jié))和一個(gè)傳感器的數(shù)據(jù)(6字節(jié))被寫入FIFO。
○ 因此,每個(gè)水印閾值單位對(duì)應(yīng)的大小是7字節(jié)(1字節(jié)的TAG加上6字節(jié)的傳感器數(shù)據(jù))。
下面代碼設(shè)置了FIFO的水印閾值。當(dāng)FIFO中存儲(chǔ)的數(shù)據(jù)達(dá)到該閾值時(shí),傳感器會(huì)產(chǎn)生一個(gè)中斷信號(hào),以通知主處理器讀取數(shù)據(jù)。水印值是未讀傳感器數(shù)據(jù)TAG和6個(gè)字節(jié)的數(shù)據(jù)樣本總數(shù)。
lsm6dsv16x_fifo_watermark_set(&dev_ctx, FIFO_WATERMARK);
在配置LSM6DSV16X傳感器的FIFO功能時(shí),每個(gè)傳感器數(shù)據(jù)樣本的大小為6字節(jié)。這是因?yàn)榧铀俣扔?jì)和陀螺儀的每個(gè)數(shù)據(jù)樣本都包含三個(gè)軸向的數(shù)據(jù),每個(gè)軸向的數(shù)據(jù)用2字節(jié)表示。具體來說:
● 加速度計(jì)數(shù)據(jù):包含X、Y、Z三個(gè)軸向的數(shù)據(jù),每個(gè)軸向的數(shù)據(jù)大小為2字節(jié)。因此,加速度計(jì)的一個(gè)完整數(shù)據(jù)樣本大小為3軸 * 2字節(jié) = 6字節(jié)。
● 陀螺儀數(shù)據(jù):同樣包含X、Y、Z三個(gè)軸向的數(shù)據(jù),每個(gè)軸向的數(shù)據(jù)大小也是2字節(jié)。因此,陀螺儀的一個(gè)完整數(shù)據(jù)樣本大小也是3軸 * 2字節(jié) = 6字節(jié)。
#define FIFO_WATERMARK 64的定義是為了在FIFO中存儲(chǔ)64個(gè)樣本后觸發(fā)中斷。因?yàn)槊總€(gè)樣本大小為7字節(jié)(1字節(jié)的TAG和6字節(jié)的傳感器數(shù)據(jù)),所以當(dāng)FIFO中存儲(chǔ)的數(shù)據(jù)達(dá)到448字節(jié)(64 * 7字節(jié))時(shí),會(huì)觸發(fā)中斷通知主處理器讀取數(shù)據(jù)。
這可以通過以下公式計(jì)算:
水印閾值字節(jié)數(shù)=64×(1字節(jié)的TAG+6字節(jié)的傳感器數(shù)據(jù))=448字節(jié)
這個(gè)設(shè)置可以確保在適當(dāng)?shù)臅r(shí)間間隔內(nèi)讀取數(shù)據(jù),既避免了頻繁中斷帶來的開銷,又不會(huì)因?yàn)镕IFO溢出而丟失數(shù)據(jù)。
設(shè)置速率
LSM6DSV16X傳感器的FIFO控制寄存器3(FIFO_CTRL3)的內(nèi)容,該寄存器用于選擇陀螺儀和加速度計(jì)數(shù)據(jù)寫入FIFO的批處理數(shù)據(jù)速率(BDR,Batch Data Rate)。以下是詳細(xì)描述:
FIFO_CTRL3寄存器(地址09h),該寄存器包含兩個(gè)主要字段:
● BDR_GY_[3:0]:選擇陀螺儀數(shù)據(jù)的批處理速率。
● BDR_XL_[3:0]:選擇加速度計(jì)數(shù)據(jù)的批處理速率。
將加速度計(jì)的數(shù)據(jù)速率(Output Data Rate, ODR)設(shè)置為60Hz。這意味著加速度計(jì)的數(shù)據(jù)將以每秒60次的頻率批量寫入FIFO。
將陀螺儀的數(shù)據(jù)速率設(shè)置為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模式,并提供以下選項(xiàng):
FIFO_MODE_[2:0] 字段用于選擇FIFO模式,詳細(xì)描述如下:
000: 旁路模式(FIFO禁用,默認(rèn))
001: FIFO模式(當(dāng)FIFO滿時(shí)停止收集數(shù)據(jù))
010: 連續(xù)模式直到水印標(biāo)志被設(shè)置為滿模式(FIFO水印標(biāo)志設(shè)置為滿模式之前,連續(xù)模式)
011: 連續(xù)模式直到解除觸發(fā),之后為FIFO模式
100: 旁路到連續(xù)模式(旁路模式直到解除觸發(fā),之后為連續(xù)模式)
101: 保留
110: 連續(xù)模式(如果FIFO滿了,新樣本將覆蓋舊的樣本)
111: 旁路到FIFO模式(旁路模式直到解除觸發(fā),之后為FIFO模式)
使用流模式有以下優(yōu)點(diǎn):
持續(xù)數(shù)據(jù)采集:適用于需要連續(xù)監(jiān)控的場(chǎng)景,如運(yùn)動(dòng)跟蹤和實(shí)時(shí)監(jiān)控應(yīng)用。
數(shù)據(jù)最新性:始終獲取到最新的數(shù)據(jù),避免數(shù)據(jù)滯后。
無需等待FIFO清空:當(dāng)FIFO填滿時(shí),新數(shù)據(jù)自動(dòng)覆蓋舊數(shù)據(jù),無需手動(dòng)清空FIFO。
/* Set FIFO mode to Stream mode (aka Continuous Mode) */
lsm6dsv16x_fifo_mode_set(&dev_ctx, LSM6DSV16X_STREAM_MODE);
設(shè)置FIFO時(shí)間戳批處理速率
LSM6DSV16X傳感器的時(shí)間戳批處理速率、溫度數(shù)據(jù)批處理速率、增強(qiáng)的EIS陀螺儀輸出批處理,以及FIFO的工作模式。這些配置確保傳感器數(shù)據(jù)能夠以適當(dāng)?shù)乃俾屎湍J竭M(jìn)行批處理和存儲(chǔ),以滿足不同的應(yīng)用需求。
/* 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);
使能時(shí)間戳
FUNCTIONS_ENABLE寄存器(地址50h) 的TIMESTAMP_EN可以使能時(shí)間戳計(jì)數(shù)器。計(jì)數(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)用于標(biāo)識(shí)存儲(chǔ)在FIFO中的傳感器數(shù)據(jù)類型。以下是詳細(xì)解釋:
字段:
TAG_SENSOR_[4:0]:用于標(biāo)識(shí)存儲(chǔ)在FIFO中的傳感器數(shù)據(jù)類型。
TAG_CNT_[1:0]:用于標(biāo)識(shí)傳感器時(shí)間槽的2位計(jì)數(shù)器。
LSM6DSV16X傳感器的FIFO數(shù)據(jù)輸出寄存器用于讀取FIFO中的X軸、Y軸和Z軸數(shù)據(jù)。以下是詳細(xì)解釋:
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]。
其中時(shí)間戳速度單位為21.75us。
演示
實(shí)際測(cè)試如下所示,數(shù)據(jù)為64個(gè)數(shù)據(jù)。
加速度速率為60Hz,角速度速率為15Hz,所以數(shù)據(jù)輸出基本上為4個(gè)ACC數(shù)據(jù)一個(gè)GYR數(shù)據(jù)。
時(shí)間戳速率60Hz/8為7.5Hz(133.33ms),大概8個(gè)ACC數(shù)據(jù)之后出現(xiàn)一個(gè)時(shí)間戳數(shù)據(jù)。
下圖中的2個(gè)時(shí)間戳數(shù)據(jù)為81998618和81992474,81998618-81992474=6144*21.75us=133.632ms
審核編輯 黃宇
-
陀螺儀
+關(guān)注
關(guān)注
44文章
783瀏覽量
98665 -
fifo
+關(guān)注
關(guān)注
3文章
387瀏覽量
43648 -
AI
+關(guān)注
關(guān)注
87文章
30728瀏覽量
268886
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論