計(jì)步器
最近在弄ST和瑞薩RA的課程,需要樣片的可以加群申請(qǐng):615061293 。
本文將介紹如何驅(qū)動(dòng)和利用LIS2DUX12傳感器,實(shí)現(xiàn)計(jì)步器感應(yīng)功能。
LIS2DUX12是一款數(shù)字式智能3軸線性加速度計(jì),其MEMS和ASIC旨在將盡可能低的電流消耗與豐富的特性(如常開抗混疊濾波、有限狀態(tài)機(jī) (FSM)、具有自適應(yīng)自配置 (ASC) 的機(jī)器學(xué)習(xí)內(nèi)核 (MLC))相結(jié)合。
FSM和MLC(帶有ASC)為L(zhǎng)IS2DUX12提供了始終可用的出色邊緣處理能力。LIS2DUX12 MIPI I3C?從接口和嵌入式128級(jí)FIFO緩沖區(qū)構(gòu)成了一系列功能,這讓該加速度計(jì)在物料清單、處理能力和功耗上成為系統(tǒng)集成方面的參考。
LIS2DUX12具有±2g/±4g/±8g/±16g的用戶可選滿量程,并且可通過1.6 Hz到800 Hz的輸出數(shù)據(jù)速率測(cè)量加速度。
LIS2DUX12包含專用內(nèi)部引擎,用于處理運(yùn)動(dòng)和加速度檢測(cè),包括自由落體、喚醒、單/雙/三擊識(shí)別、活動(dòng)/休止,以及6D/4D方向。
LIS2DUX12采用纖薄的小型塑料平面網(wǎng)格陣列封裝(LGA),可確保在更大的溫度范圍(-40°C至+85°C)內(nèi)正常工作。
硬件準(zhǔn)備
首先需要準(zhǔn)備一個(gè)開發(fā)板,這里我準(zhǔn)備的是自己繪制的開發(fā)板,需要的可以進(jìn)行申請(qǐng)。 主控為STM32U073CC,加速度計(jì)為L(zhǎng)IS2DUX12
視頻教學(xué)
[https://www.bilibili.com/video/BV1ci421X7bh/]
樣品申請(qǐng)
[https://www.wjx.top/vm/OhcKxJk.aspx#]
源碼下載
[https://download.csdn.net/download/qq_24312945/89283492]
步數(shù)檢測(cè)說明
LIS2DUX12 集成了一個(gè)高級(jí)步數(shù)計(jì)算法,該算法在超低功耗域中運(yùn)行,確保在電池受限的應(yīng)用中延長(zhǎng)電池壽命。步數(shù)計(jì)以 25 Hz 運(yùn)行,不受所選設(shè)備功率模式(超低功耗、低功耗、高性能)的影響,保證超低功耗體驗(yàn)并與其他設(shè)備功能靈活結(jié)合。 步數(shù)計(jì)算法由以下四個(gè)階段組成:
- 計(jì)算加速度量級(jí)信號(hào)的峰值:檢測(cè)信號(hào)中的峰值以識(shí)別步數(shù),獨(dú)立于設(shè)備的方向。
- FIR 濾波器:提取相關(guān)頻率成分并通過去除高頻信號(hào)來平滑信號(hào)。
- 峰值檢測(cè)器:找到波形的最大值和最小值并計(jì)算峰峰值。
- 步數(shù)計(jì)數(shù):如果峰峰值大于設(shè)定的閾值,則計(jì)為一步。
通信模式
對(duì)于LIS2DW12,可以使用SPI或者IIC進(jìn)行通訊。 最小系統(tǒng)圖如下所示。
在CS管腳為1的時(shí)候,為IIC模式
本文使用的板子原理圖如下所示。
管腳定義
IIC通信模式
在使用IIC通訊模式的時(shí)候,SA0是用來控制IIC的地址位的。
對(duì)于IIC的地址,可以通過SDO/SA0引腳修改。SDO/SA0引腳可以用來修改設(shè)備地址的最低有效位。如果SDO/SA0引腳連接到電源電壓,LSb(最低有效位)為’1’(地址0011001b);否則,如果SDO/SA0引腳連接到地線,LSb的值為’0’(地址0011000b)。
對(duì)應(yīng)的IIC接口如下所示。 主要使用的管腳為CS、SCL、SDA、SA0。
速率
該模塊支持的速度為普通模式(100k)到快速模式+(1M)。
生成STM32CUBEMX
用STM32CUBEMX生成例程,這里使用MCU為STM32U073CC。 配置時(shí)鐘樹,配置時(shí)鐘為48M。
IIC配置
配置IIC為快速模式,速度為400k。
INT配置
INT1管腳為PB1。
配置如下所示。
開啟中斷。
配置LED指示燈。
stm32u0xx_it.c添加中斷觸發(fā)后LED翻轉(zhuǎn)電平的代碼,添加對(duì)應(yīng)變量。
/* USER CODE BEGIN 0 */
extern uint8_t step_event ;
/* USER CODE END 0 */
添加中斷代碼。
/**
* @brief This function handles EXTI line 0 and line 1 interrupts.
*/
void EXTI0_1_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_1_IRQn 0 */
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_1);
step_event = 1;
/* USER CODE END EXTI0_1_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
/* USER CODE BEGIN EXTI0_1_IRQn 1 */
/* USER CODE END EXTI0_1_IRQn 1 */
}
串口配置
查看原理圖,PA9和PA10設(shè)置為開發(fā)板的串口。
配置串口。
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/lis2dux12-pid]
計(jì)步器參考
[https://github.com/stm32duino/LIS2DUXS12/tree/main/examples]
初始換管腳
由于需要向LIS2DUX12_I2C_ADD_L寫入以及為IIC模式。
所以使能CS為高電平,配置為IIC模式。 配置SA0為低電平。
HAL_GPIO_WritePin(GPIOC, CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, SA0_Pin, GPIO_PIN_SET);
獲取ID
我們可以向WHO_AM_I (0Fh)獲取固定值,判斷是否為0x47。
lis2dux12_device_id_get為獲取函數(shù)。
對(duì)應(yīng)的獲取ID驅(qū)動(dòng)程序,如下所示。
printf("HELLOn");
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(SA0_GPIO_Port, SA0_Pin, GPIO_PIN_RESET);
lis2dux12_status_t status;
uint8_t id;
lis2dux12_md_t md;
uint16_t steps = 0;
lis2dux12_int_config_t int_mode;
/* 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;
/* Wait sensor boot time */
platform_delay(BOOT_TIME);
lis2dux12_exit_deep_power_down(&dev_ctx);// 退出深度休眠模式
/* Check device ID */
lis2dux12_device_id_get(&dev_ctx, &id);
printf("LIS2DUX12_ID=0x%x,id=0x%xn",LIS2DUX12_ID,id);
if (id != LIS2DUX12_ID)
while(1);
/* Restore default configuration */
lis2dux12_init_set(&dev_ctx, LIS2DUX12_RESET);// 重置設(shè)備
do {
lis2dux12_status_get(&dev_ctx, &status);// 獲取設(shè)備狀態(tài)
} while (status.sw_reset);// 獲取設(shè)備狀態(tài)
復(fù)位操作
可以向CTRL1 (10h)的SW_RESET寄存器寫入1進(jìn)行復(fù)位。
lis2dux12_init_set為重置函數(shù)。 對(duì)應(yīng)的驅(qū)動(dòng)程序,如下所示。
/* Restore default configuration */
lis2dux12_init_set(&dev_ctx, LIS2DUX12_RESET);
do {
lis2dux12_status_get(&dev_ctx, &status);
} while (status.sw_reset);
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ù)。
簡(jiǎn)而言之,BDU位的作用是確保在讀取數(shù)據(jù)時(shí),輸出寄存器的內(nèi)容保持穩(wěn)定,從而避免讀取到拼湊或錯(cuò)誤的數(shù)據(jù)。這對(duì)于需要高精度和穩(wěn)定性的應(yīng)用尤為重要。
可以向CTRL4 (13h)的BDU寄存器寫入1進(jìn)行開啟。
對(duì)應(yīng)的驅(qū)動(dòng)程序,如下所示。
/* Set bdu and if_inc recommended for driver usage */
lis2dux12_init_set(&dev_ctx, LIS2DUX12_SENSOR_ONLY_ON);
設(shè)置傳感器的量程
FS[1:0] - 全量程選擇:這兩個(gè)位用于設(shè)置傳感器的量程。量程決定了傳感器可以測(cè)量的最大加速度值。例如,量程可以設(shè)置為±2g、±4g、±8g或±16g。這允許用戶根據(jù)應(yīng)用的特定需求調(diào)整傳感器的靈敏度。
對(duì)應(yīng)的驅(qū)動(dòng)程序,如下所示。
/* Set Output Data Rate */
md.fs = LIS2DUX12_4g;
md.odr = LIS2DUX12_25Hz_LP;
lis2dux12_mode_set(&dev_ctx, &md);
啟用步數(shù)計(jì)和嵌入式功能
EMB_FUNC_EN 是一個(gè)寄存器位,用于啟用 LIS2DUX12 傳感器的嵌入式功能。這些嵌入式功能可能包括傳感器的各種高級(jí)特性,如步數(shù)計(jì)、活動(dòng)檢測(cè)、自由落體檢測(cè)等。這些功能通過內(nèi)部算法處理傳感器數(shù)據(jù),而不需要主機(jī)處理器進(jìn)行復(fù)雜計(jì)算,從而減輕了主機(jī)處理器的負(fù)擔(dān)。
if_add_inc 是一個(gè)控制寄存器位,用于啟用或禁用自動(dòng)地址遞增功能。在多字節(jié)訪問模式下,當(dāng)你讀取或?qū)懭攵鄠€(gè)連續(xù)的寄存器時(shí),啟用地址遞增功能可以使得寄存器地址自動(dòng)增加。這在讀取或?qū)懭胍幌盗袛?shù)據(jù)時(shí)非常有用,因?yàn)樗梢詼p少通信開銷并簡(jiǎn)化代碼。
// Enable Pedometer.
/* 啟用傳感器的嵌入式功能(例如,步數(shù)計(jì)),這通常推薦用于驅(qū)動(dòng)程序 */
lis2dux12_init_set(&dev_ctx, LIS2DUX12_SENSOR_EMB_FUNC_ON);// 啟用嵌入式功能
platform_delay(10);
PEDO_EN 是一個(gè)用于啟用步數(shù)檢測(cè)功能的控制位。啟用此功能后,傳感器可以進(jìn)行步數(shù)計(jì)數(shù)。這在運(yùn)動(dòng)檢測(cè)和健康監(jiān)控應(yīng)用中非常重要,因?yàn)樗梢杂涗浻脩舻牟綌?shù)數(shù)據(jù)。
lis2dux12_stpcnt_mode_t mode;
lis2dux12_stpcnt_mode_get(&dev_ctx, &mode);// 獲取步數(shù)計(jì)模式
/* Enable pedometer algorithm. */
mode.step_counter_enable = PROPERTY_ENABLE;// 啟用步數(shù)計(jì)
mode.false_step_rej = PROPERTY_DISABLE;// 禁用誤步拒絕功能
mode.step_counter_in_fifo = PROPERTY_DISABLE; // 禁用步數(shù)計(jì) FIFO
/* Turn on embedded features */
lis2dux12_stpcnt_mode_set(&dev_ctx, mode) ;// 設(shè)置步數(shù)計(jì)模式
配置步數(shù)檢測(cè)中斷引腳
INT1_STEP_DET 是一個(gè)用于步數(shù)檢測(cè)中斷的寄存器位。當(dāng)啟用這個(gè)中斷位時(shí),LIS2DUX12 傳感器在檢測(cè)到步數(shù)事件時(shí)會(huì)觸發(fā)中斷信號(hào),并將該信號(hào)輸出到指定的中斷引腳(如 INT1)。這使得主機(jī)微控制器可以通過中斷響應(yīng)步數(shù)檢測(cè)事件,而不需要不斷輪詢傳感器的狀態(tài)。
INT1_EMB_FUNC 是一個(gè)用于配置 LIS2DUX12 傳感器的嵌入式功能中斷的寄存器位。當(dāng)該位啟用時(shí),傳感器會(huì)在嵌入式功能(例如步數(shù)檢測(cè)、活動(dòng)檢測(cè)等)觸發(fā)事件時(shí)通過 INT1 引腳發(fā)出中斷信號(hào)。這個(gè)功能使得主機(jī)微控制器可以通過中斷快速響應(yīng)傳感器的嵌入式功能事件,而不需要持續(xù)輪詢傳感器狀態(tài)。
lis2dux12_emb_pin_int_route_t emb_pin_int;
lis2dux12_emb_pin_int1_route_get(&dev_ctx, &emb_pin_int);// 設(shè)置步數(shù)計(jì)模式
emb_pin_int.step_det = PROPERTY_ENABLE;// 設(shè)置步數(shù)計(jì)模式
lis2dux12_emb_pin_int1_route_set(&dev_ctx, &emb_pin_int);// 設(shè)置嵌入式中斷引腳
中斷檢測(cè)步數(shù)
可以通過判斷 INT1_STEP_DET 位來確定步數(shù)事件是否產(chǎn)生。根據(jù)您提供的截圖,INT1_STEP_DET 位位于 EMB_FUNC_INT1 寄存器中。當(dāng)這個(gè)位被設(shè)置為 1 時(shí),表示步數(shù)檢測(cè)中斷被路由到 INT1 引腳。因此,您可以通過讀取該寄存器來判斷步數(shù)事件是否產(chǎn)生。
EMB_FUNC_REG_ACCESS 是用于訪問和配置 LIS2DUX12 傳感器的嵌入式功能寄存器的寄存器位。啟用 EMB_FUNC_REG_ACCESS 后,可以訪問和配置與嵌入式功能相關(guān)的寄存器。這對(duì)于啟用步數(shù)檢測(cè)、活動(dòng)檢測(cè)、自由落體檢測(cè)等功能非常重要。
獲取步數(shù)可以通過STEP_COUNTER_L (28h) 和 STEP_COUNTER_H (29h)進(jìn)行獲取。
獲取完畢之后關(guān)閉EMB_FUNC_REG_ACCESS 。
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if (step_event) {
lis2dux12_emb_pin_int_route_t emb_pin_int1;
lis2dux12_emb_pin_int1_route_get(&dev_ctx, &emb_pin_int1);
if (emb_pin_int1.step_det)
{
lis2dux12_stpcnt_steps_get(&dev_ctx, &steps);
/* print number of steps */
printf("Steps: %drn", steps);
}
step_event = 0;
}
HAL_Delay(10);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
演示
審核編輯 黃宇
-
傳感器
+關(guān)注
關(guān)注
2552文章
51272瀏覽量
755044 -
加速度計(jì)
+關(guān)注
關(guān)注
6文章
703瀏覽量
45929 -
計(jì)步器
+關(guān)注
關(guān)注
4文章
76瀏覽量
19945 -
stm32cubemx
+關(guān)注
關(guān)注
5文章
283瀏覽量
14867
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論