概述
本文介紹如何初始化傳感器并配置其參數(shù),以便在檢測(cè)到自由落體事件時(shí)發(fā)送通知。
最近在弄ST和瑞薩RA的課程,需要樣片的可以加群申請(qǐng):615061293 。
視頻教學(xué)
[https://www.bilibili.com/video/BV1yi421o7Jr/]
樣品申請(qǐng)
[https://www.wjx.top/vm/OhcKxJk.aspx#]
源碼下載
[https://download.csdn.net/download/qq_24312945/88947607]
生成STM32CUBEMX
用STM32CUBEMX生成例程,這里使用MCU為STM32WB55RG。 配置時(shí)鐘樹(shù),配置時(shí)鐘為32M。
串口配置
查看原理圖,PB6和PB7設(shè)置為開(kāi)發(fā)板的串口。
配置串口。
IIC配置
配置IIC為快速模式,速度為400k。
CS和SA0設(shè)置
串口重定向
打開(kāi)魔術(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寫(xiě)入以及為IIC模式。
所以使能CS為高電平,配置為IIC模式。 配置SA0為高電平。
printf("123123123");
lsm6dsv16x_reset_t rst;
stmdev_ctx_t dev_ctx;
/* Initialize mems driver interface */
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;
dev_ctx.handle = &SENSOR_BUS;
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(SA0_GPIO_Port, SA0_Pin, GPIO_PIN_RESET);
獲取ID
可以向WHO_AM_I (0Fh)獲取固定值,判斷是否為0x70。
lsm6dsv16x_device_id_get為獲取函數(shù)。
對(duì)應(yīng)的獲取ID驅(qū)動(dòng)程序,如下所示。
/* Wait sensor boot time */
platform_delay(BOOT_TIME);
/* 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寄存器寫(xiě)入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è)問(wèn)題:當(dāng)你讀取MSB時(shí),如果寄存器更新了,接下來(lái)讀取的LSB可能就是新的測(cè)量值的一部分,而不是與MSB相對(duì)應(yīng)的值。這樣,你得到的就是一個(gè)“拼湊”的數(shù)據(jù),它可能無(wú)法準(zhǔn)確代表任何實(shí)際的測(cè)量時(shí)刻。
塊數(shù)據(jù)更新(BDU)模式(BDU = ‘1’):當(dāng)激活BDU功能時(shí),輸出寄存器中的內(nèi)容不會(huì)在讀取MSB和LSB之間更新。這就意味著一旦開(kāi)始讀取數(shù)據(jù)(無(wú)論是先讀MSB還是LSB),寄存器中的那一組數(shù)據(jù)就被“鎖定”,直到兩部分都被讀取完畢。這樣可以確保你讀取的MSB和LSB是同一測(cè)量時(shí)刻的數(shù)據(jù),避免了讀取到代表不同采樣時(shí)刻的數(shù)據(jù)。
簡(jiǎn)而言之,BDU位的作用是確保在讀取數(shù)據(jù)時(shí),輸出寄存器的內(nèi)容保持穩(wěn)定,從而避免讀取到拼湊或錯(cuò)誤的數(shù)據(jù)。這對(duì)于需要高精度和穩(wěn)定性的應(yīng)用尤為重要。
可以向CTRL3 (12h)的BDU寄存器寫(xiě)入1進(jìn)行開(kāi)啟。
對(duì)應(yīng)的驅(qū)動(dòng)程序,如下所示。
/* Enable Block Data Update */
lsm6dsv16x_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
寄存器地址自動(dòng)遞增
IF_INC (Register Address Auto-Increment):
當(dāng)使用串行接口(如I2C, MIPI I3C, 或 SPI)進(jìn)行多字節(jié)訪問(wèn)時(shí),此位用于自動(dòng)增加寄存器地址。默認(rèn)值是1(啟用),這樣在連續(xù)讀取多個(gè)寄存器時(shí),地址會(huì)自動(dòng)遞增
對(duì)應(yīng)的驅(qū)動(dòng)程序,如下所示。
/* Enable register address automatically incremented during a multiple byte
access with a serial interface. */
lsm6dsv16x_auto_increment_set(&dev_ctx, PROPERTY_ENABLE) ;
關(guān)閉FIFO
可以通過(guò)FIFO_CTRL4 (0Ah)關(guān)閉FIFO模式。
對(duì)應(yīng)的驅(qū)動(dòng)程序,如下所示。
/* FIFO mode selection */
lsm6dsv16x_fifo_mode_set(&dev_ctx, LSM6DSV16X_BYPASS_MODE);
設(shè)置量程
加速度量程可以通過(guò)CTRL8 (17h)的CTRL8 (17h)設(shè)置。
對(duì)應(yīng)的驅(qū)動(dòng)程序,如下所示。
/* Full scale selection. */
lsm6dsv16x_xl_full_scale_set(&dev_ctx, LSM6DSV16X_2g);
關(guān)閉角速度量程
陀螺儀的輸出數(shù)據(jù)率選擇可以通過(guò)CTRL2 (11h) 陀螺儀控制寄存器進(jìn)行配置。由于不需要用到陀螺儀數(shù)據(jù),所以可以關(guān)閉。
對(duì)應(yīng)的驅(qū)動(dòng)程序,如下所示。
/* Output data rate selection - power down. */
lsm6dsv16x_gy_data_rate_set(&dev_ctx, LSM6DSV16X_ODR_OFF);
輸出數(shù)據(jù)設(shè)置
輸出數(shù)據(jù)率范圍從1.875 Hz到7.68 kHz不等,允許用戶根據(jù)應(yīng)用的需求來(lái)調(diào)整加速度計(jì)的性能和功耗。
CTRL1 (10h) 加速度計(jì)控制寄存器的配置選項(xiàng)。
對(duì)應(yīng)的驅(qū)動(dòng)程序,如下所示。
/* Output data rate selection. */
lsm6dsv16x_xl_data_rate_set(&dev_ctx, LSM6DSV16X_ODR_AT_120Hz);
設(shè)置自由落體功能的持續(xù)時(shí)間
WAKE_UP_DUR (5Ch) 寄存器用于設(shè)置自由落體、喚醒和睡眠模式功能的持續(xù)時(shí)間。具體字段如下:
FF_DUR_5:與自由落體持續(xù)時(shí)間事件相關(guān)。完整的自由落體配置需要參考 FREE_FALL 寄存器。
WAKE_DUR [1:0]:定義喚醒事件的持續(xù)時(shí)間,默認(rèn)值為00。
SLEEP_DUR [3:0]:定義進(jìn)入睡眠模式前的持續(xù)時(shí)間,默認(rèn)值為0000。
FREE_FALL (5Dh) 寄存器用于設(shè)置自由落體功能的持續(xù)時(shí)間和閾值。具體字段如下:
FF_DUR [4:0]:定義自由落體事件的持續(xù)時(shí)間,需要與 WAKE_UP_DUR 寄存器的 FF_DUR_5 位一起配置以設(shè)置完整的持續(xù)時(shí)間。
FF_THS [2:0]:定義自由落體檢測(cè)的閾值,默認(rèn)值為000。
對(duì)應(yīng)的驅(qū)動(dòng)程序,如下所示。
/* Set free fall duration.*/
lsm6dsv16x_ff_time_windows_set(&dev_ctx, 0x06);
中斷設(shè)置
MD1_CFG (5Eh) 這個(gè)寄存器用于配置哪些功能的中斷信號(hào)會(huì)被路由到 INT1 引腳。每個(gè)位的設(shè)置決定了特定事件是否會(huì)觸發(fā) INT1 引腳的中斷。具體功能如下:
INT1_SLEEP_CHANGE:活動(dòng)/靜止?fàn)顟B(tài)變化的中斷事件路由到 INT1。
INT1_SINGLE_TAP:?jiǎn)未吻脫糇R(shí)別的中斷事件路由到 INT1。
INT1_WU:?jiǎn)拘咽录闹袛嗦酚傻?INT1。
INT1_FF:自由落體事件的中斷路由到 INT1。
INT1_DOUBLE_TAP:雙次敲擊識(shí)別的中斷事件路由到 INT1。
INT1_6D:6D(方向改變)事件的中斷路由到 INT1。
INT1_EMB_FUNC:嵌入式功能事件的中斷路由到 INT1。
INT1_SHUB:傳感器集線器通信結(jié)束的中斷路由到 INT1。
每個(gè)功能旁邊的 0 和 1 表示該功能的中斷是否被禁用 (0) 或啟用 (1)。默認(rèn)值是 0,表示中斷被禁用。如果將相應(yīng)位設(shè)置為 1,則當(dāng)相應(yīng)的事件發(fā)生時(shí),INT1 引腳將觸發(fā)中斷。
通過(guò)這個(gè)寄存器,開(kāi)發(fā)者可以根據(jù)需要配置傳感器,以確定在發(fā)生如敲擊、喚醒、自由落體或方向改變等事件時(shí)是否生成中斷信號(hào),從而允許外部微控制器或處理器相應(yīng)地響應(yīng)這些事件。
FUNCTIONS_ENABLE(50h)這個(gè)寄存器用于控制不同的中斷功能是否啟用。具體功能包括:
INTERRUPTS_ENABLE:?jiǎn)⒂没蚪没局袛啵?D/4D定向、自由落體、喚醒、敲擊、活動(dòng)/靜止)。默認(rèn)值為0,表示中斷禁用。 TIMESTAMP_EN:?jiǎn)⒂没蚪脮r(shí)間戳計(jì)數(shù)器。如果啟用,時(shí)間戳計(jì)數(shù)器的值可以在TIMESTAMP0(40h)、TIMESTAMP1(41h)和TIMESTAMP3(43h)寄存器中讀取。默認(rèn)值為0,表示禁用。 DIS_RST_LIR_ALL_INT:當(dāng)此位設(shè)置為1時(shí),讀取ALL_INT_SRC(1Dh)寄存器不會(huì)重置鎖存的中斷信號(hào)。這在讀取狀態(tài)寄存器之前不重置某些狀態(tài)標(biāo)志時(shí)很有用。默認(rèn)值為0。 INACT_EN [1:0]:?jiǎn)⒂没顒?dòng)/靜止(睡眠)功能。根據(jù)設(shè)置,這可以配置加速度計(jì)進(jìn)入不同的低功耗模式,并通過(guò)INACTIVITY_DUR(54h)寄存器選擇加速度計(jì)的輸出數(shù)據(jù)速率(ODR)。陀螺儀的配置也可能相應(yīng)變化,例如進(jìn)入睡眠模式或關(guān)閉電源模式。
這個(gè)寄存器讓用戶可以根據(jù)應(yīng)用需求,靈活地選擇哪些中斷事件應(yīng)該被監(jiān)控,以及加速度計(jì)和陀螺儀的功耗管理策略。這些設(shè)置對(duì)于優(yōu)化設(shè)備電池壽命和確保及時(shí)響應(yīng)傳感器事件非常重要。
對(duì)應(yīng)的驅(qū)動(dòng)程序,如下所示。
/* Enable free fall event on either INT1 or INT2 pin */
lsm6dsv16x_md1_cfg_t val1;
lsm6dsv16x_functions_enable_t functions_enable;
lsm6dsv16x_read_reg(&dev_ctx, LSM6DSV16X_MD1_CFG, (uint8_t *)&val1, 1);
val1.int1_ff = PROPERTY_ENABLE;
lsm6dsv16x_write_reg(&dev_ctx, LSM6DSV16X_MD1_CFG, (uint8_t *)&val1, 1);
lsm6dsv16x_read_reg(&dev_ctx, LSM6DSV16X_FUNCTIONS_ENABLE, (uint8_t *)&functions_enable, 1);
functions_enable.interrupts_enable = PROPERTY_ENABLE;
lsm6dsv16x_write_reg(&dev_ctx, LSM6DSV16X_FUNCTIONS_ENABLE, (uint8_t *)&functions_enable, 1);
獲取所有中斷源的狀態(tài)
可以通過(guò)ALL_INT_SRC (1Dh)寄存器的FF_IA判斷是否產(chǎn)生自由落體事件。
/* wait forever (6D event handle in irq handler) */
lsm6dsv16x_all_sources_t status;
if(HAL_GPIO_ReadPin(INT1_GPIO_Port,INT1_Pin)==0)
{
/* Read output only if new xl value is available */
lsm6dsv16x_all_sources_get(&dev_ctx, &status);
if (status.free_fall) {
printf("Free Fall Detected!n");
}
}
演示
審核編輯 黃宇
-
陀螺儀
+關(guān)注
關(guān)注
44文章
784瀏覽量
98712 -
AI
+關(guān)注
關(guān)注
87文章
30894瀏覽量
269085 -
stm32cubemx
+關(guān)注
關(guān)注
5文章
283瀏覽量
14809
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論