LSM6DSVE(1)----輪詢獲取陀螺儀數(shù)據(jù))
STM32C5開發(fā)LSM6DSVE .1--輪詢獲取陀螺儀數(shù)據(jù)概述視頻教學(xué)樣品申請源碼下載硬件準(zhǔn)備參考程序所有功能串口配置通信模式管腳定義IIC通信模式速率IIC配置CS和SA0設(shè)置生成項目導(dǎo)入STM32CubeIDE設(shè)置工程編碼添加頭文件printf 重定向參考程序CMake設(shè)置頭文件設(shè)置初始換管腳獲取ID復(fù)位傳感器BDU設(shè)置配置輸出數(shù)據(jù)率與測量量程配置加速度計低通濾波器輪詢讀取傳感器數(shù)據(jù)演示.1–輪詢獲取陀螺儀數(shù)據(jù))概述LSM6DSVE是一款高端、低噪聲、低功耗的6軸小型IMU配備了一個3軸數(shù)字加速度計和一個3軸數(shù)字陀螺儀擁有最好的IMU傳感器三溝道架構(gòu)可以在三個獨立的溝道用戶界面、OIS和EIS上處理加速度和角速率數(shù)據(jù)具有專用的配置、處理和過濾功能。LSM6DSVE支持邊緣計算中的處理過程利用嵌入式高級專用功能如低功耗的傳感器融合 (SFLP) 算法和可配置運動跟蹤的有限狀態(tài)機(jī) (FSM)。LSM6DSVE支持自適應(yīng)自配置 (ASC) 功能允許FSM在檢測到特定運動模式時自動實時重新配置器件無需主處理器的任何干預(yù)。需要樣片的可以加群申請925643491 / 615061293 。視頻教學(xué)https://www.bilibili.com/video/BV1wa3j61EsH/樣品申請https://www.wjx.top/vm/OhcKxJk.aspx#源碼下載https://download.csdn.net/download/qq_24312945/93287426硬件準(zhǔn)備首先需要準(zhǔn)備一個開發(fā)板這里我準(zhǔn)備的是自己繪制的開發(fā)板需要的可以進(jìn)行申請。主控為STM32C542CC陀螺儀為LSM6DSVE磁力計為LIS2MDL。參考程序https://github.com/CoreMaker-lab/STM32C542_LSM6DSVE_LIS2MDLhttps://gitee.com/CoreMaker/STM32C542_LSM6DSVE_LIS2MDL所有功能● 三溝道架構(gòu)支持UI、EIS以及OIS數(shù)據(jù)處理● 低功耗的加速度計和陀螺儀帶來“常開”體驗● 高達(dá)4.5 KB的智能FIFO● 與Android兼容● ±2/±4/±8/±16 g滿量程● ±125/±250/±500/±1000/±2000/±4000 dps 滿量程● SPI/I2C和MIPI I3C? v1.1串行接口支持主處理器數(shù)據(jù)同步功能● 輔助SPI用于陀螺儀和加速度計的OIS數(shù)據(jù)輸出● OIS可從aux配置SPI主接口 (SPI/I2C MIPI I3C? v1.1)● 主接口上的EIS專用通道具有專用濾波功能● 高級計步器步伐偵測和步數(shù)計算● 大幅運動檢測傾斜度檢測● 標(biāo)準(zhǔn)中斷自由落體、喚醒、6D/4D方向檢測、單擊和雙擊● 可編程有限狀態(tài)機(jī)用于加速度計、陀螺儀以及外部傳感器數(shù)據(jù)處理960 Hz高速率● 嵌入式自適應(yīng)自配置 (ASC)● 內(nèi)嵌低功耗傳感器融合算法● 嵌入式溫度傳感器● 模擬供電電壓1.71 V到3.6 V● 獨立IO供電擴(kuò)展的范圍1.08 V - 3.6 V● 功耗在組合高性能模式下為0.65 mA● 緊湊外形2.5 mm x 3 mm x 0.83 mm● 符合ECOPACK和RoHS標(biāo)準(zhǔn)串口配置查看原理圖PA9和PA10設(shè)置為開發(fā)板的串口。在左側(cè) Peripherals 中選擇 Connectivity → USART1Mode 選擇 Async表示配置為異步串口模式Function used by the component 顯示為 UART說明 USART1 在異步模式下使用 UART HAL 驅(qū)動串口參數(shù)配置為115200 波特率、8 位數(shù)據(jù)位、無校驗、1 位停止位、收發(fā)模式GPIO TxUSART1_TX 選擇 PA9GPIO RxUSART1_RX 選擇 PA10PA9 / PA10 均配置為 Alternate 復(fù)用功能模式Pull 選擇 No pull-up and no pull-downOutput type 選擇 Push pullSpeed 選擇 Low通信模式于LSM6DSVE可以使用SPI或者IIC進(jìn)行通訊。最小系統(tǒng)圖如下所示。在CS管腳為1的時候為IIC模式。本文使用的板子原理圖如下所示。管腳定義IIC通信模式在在使用IIC通訊模式的時候SA0是用來控制IIC的地址位的。對于IIC的地址可以通過SA0引腳修改。TA0引腳可以用來修改設(shè)備地址的最低有效位。如果SA0引腳連接到電源電壓LSb最低有效位為’1’地址1101011b否則如果SA0引腳連接到地線LSb的值為’0’地址1101010b。接口如下所示。主要使用的管腳為CS、SCL、SDA、SA0。速率該模塊支持的速度為普通模式(100k)和快速模式(400k)和快速模式(1M)。IIC配置STM32C542CCT6通過擴(kuò)展接口與傳感器模塊連接其中PB6作為I2C時鐘線SCLPB7作為I2C數(shù)據(jù)線SDA首先在 STM32CubeMX2 中進(jìn)入 Peripherals 外設(shè)配置頁面在 Connectivity 分類中選擇 I2C1并將 I2C1 外設(shè)使能。如圖所示本實驗的 I2C1 配置步驟如下點擊左側(cè) Peripherals 外設(shè)配置入口在 Connectivity 分類中選擇 I2C1將 I2C1 Mode 設(shè)置為 I2C并確認(rèn) I2C1 顯示為 ActiveSpeed frequency 設(shè)置為 Fast mode - 400 kHz確認(rèn) I2C1 的 GPIO 引腳映射SCL 為 PB6SDA 為 PB7CS和SA0設(shè)置確認(rèn) LSM6DSVE 的 I2C 模式選擇和地址選擇CS 需要處于 I2C 模式對應(yīng)電平SA0 需要固定為高電平或低電平將 PA1 和 PB2 配置為普通 GPIO。在 STM32CubeMX2 的 Pinout 頁面中將 PA1 和 PB2 配置為普通 GPIO。SA0用于選擇 LSM6DSR 的 I2C 地址CS用于選擇 LSM6DSR 的通信接口模式在右側(cè) Pin signals 中將對應(yīng)引腳設(shè)置為 GPIO → Configured表示該引腳將作為普通 GPIO 使用由用戶程序控制輸出高低電平。進(jìn)入 System → GPIO 配置頁面可以看到 PA1 和 PB2 已經(jīng)被加入 GPIO 配置列表。本實驗中將 PB2 作為 CS 控制腳 , 將 PA1 作為 SA0 控制腳 。由于還有一個磁力計需要把該CS也使能。在 STM32CubeMX2 的 Pinout 頁面中將 PA6配置為普通 GPIO。進(jìn)入 System → GPIO 配置頁面 PA6 作為 CS2 控制腳 。生成項目修改配置后左下角會提示 Click to save需要先保存當(dāng)前工程配置點擊左側(cè) Project settings進(jìn)入工程生成設(shè)置頁面在 IDE Project Generation 中選擇工程格式和工具鏈本例選擇 CMake GCC然后點擊 Generate IDE project 生成工程導(dǎo)入STM32CubeIDE打開 STM32CubeIDE點擊菜單欄 File選擇 Import…準(zhǔn)備導(dǎo)入 STM32CubeMX2 生成的 CMake 工程在 Import 窗口中展開 Import STM32 Project選擇 STM32 CMake Project點擊 Next進(jìn)入 CMake 工程路徑選擇頁面Project name填寫導(dǎo)入到 STM32CubeIDE 中顯示的工程名稱Source directory選擇 STM32CubeMX2 生成的 CMake 工程目錄點擊 Next繼續(xù)完成工程導(dǎo)入Toolchain選擇 MCU ARM GCC表示使用 ARM GCC 工具鏈進(jìn)行編譯MCU確認(rèn)芯片型號為 STM32C542CCTx與前面 STM32CubeMX2 中選擇的 MCU 保持一致CPU/Core確認(rèn)內(nèi)核為 Cortex-M33Core 為 0點擊 Finish完成 CMake 工程導(dǎo)入設(shè)置工程編碼在 Project Explorer 中選中當(dāng)前工程點擊菜單欄 Project選擇 Properties進(jìn)入工程屬性設(shè)置在工程屬性中選擇 ResourceText file encoding 選擇 Other編碼格式輸入 GBK點擊 Apply and Close 保存設(shè)置添加頭文件在 main.c 中添加頭文件#includemx_usart1.h#includestdio.h#includestring.hprintf 重定向為了讓 printf() 輸出到 USART1需要重寫 _write() 函數(shù)。GCC 工程中printf() 底層會調(diào)用 _write() 輸出字符因此只需要在 _write() 中調(diào)用 HAL_UART_Transmit()就可以把 printf() 的內(nèi)容通過串口發(fā)送出去。int_write(intfile,char*ptr,intlen){hal_uart_handle_t*huart1mx_usart1_uart_gethandle();if(huart1!NULL){HAL_UART_Transmit(huart1,ptr,len,1000);}returnlen;}參考程序https://github.com/STMicroelectronics/lsm6dsv-pid添加對應(yīng)驅(qū)動程序。CMake設(shè)置把lsm6dsv_reg.c 加入 CMake 編譯 。target_sources(${CMAKE_PROJECT_NAME}PRIVATE#Add additional source files herelsm6dsv_reg.c)printf 輸出浮點數(shù)需要額外開啟 float printf 支持。CMake 官方說明 target_link_options() 就是給可執(zhí)行目標(biāo)添加 linker options 的命令。target_link_options(${CMAKE_PROJECT_NAME}PUBLIC#Add additional linker flags here-u _printf_float)頭文件設(shè)置添加頭文件。#includelsm6dsv_reg.h初始換管腳由于需要向LSM6DV_I2C_ADD_L寫入以及為IIC模式。所以使能CS為高電平配置為IIC模式。配置SA0為低電平。printf(HELLO\n);HAL_GPIO_WritePin(CS1_PORT,CS1_PIN,HAL_GPIO_PIN_SET);HAL_GPIO_WritePin(SA0_PORT,SA0_PIN,HAL_GPIO_PIN_RESET);HAL_GPIO_WritePin(CS2_PORT,CS2_PIN,HAL_GPIO_PIN_SET);變量定義。/* Private macro -------------------------------------------------------------*/#defineBOOT_TIME10//ms/* Private variables ---------------------------------------------------------*/staticint16_tdata_raw_acceleration[3];staticint16_tdata_raw_angular_rate[3];staticint16_tdata_raw_temperature;staticfloat_tacceleration_mg[3];staticfloat_tangular_rate_mdps[3];staticfloat_ttemperature_degC;staticuint8_twhoamI;staticuint8_ttx_buffer[1000];staticlsm6dsv_filt_settling_mask_tfilt_settling_mask;/* Extern variables ----------------------------------------------------------*//* Private functions ---------------------------------------------------------*//* * WARNING: * Functions declare in this section are defined at the end of this file * and are strictly related to the hardware platform used. * */staticint32_tplatform_write(void*handle,uint8_treg,constuint8_t*bufp,uint16_tlen);staticint32_tplatform_read(void*handle,uint8_treg,uint8_t*bufp,uint16_tlen);staticvoidtx_com(uint8_t*tx_buffer,uint16_tlen);staticvoidplatform_delay(uint32_tms);staticvoidplatform_init(void);獲取ID我們可以向WHO_AM_I (0Fh)獲取固定值判斷是否為0x70。對應(yīng)的獲取ID驅(qū)動程序,如下所示。lsm6dsv_all_sources_tall_sources;stmdev_ctx_tdev_ctx;/* Initialize mems driver interface */dev_ctx.write_regplatform_write;dev_ctx.read_regplatform_read;dev_ctx.mdelayplatform_delay;dev_ctx.handlemx_i2c1_i2c_gethandle();/* Init test platform */// platform_init();/* Wait sensor boot time */platform_delay(BOOT_TIME);/* Check device ID */lsm6dsv_device_id_get(dev_ctx,whoamI);printf(LSM6DSV_ID0x%x,id0x%x\n,LSM6DSV_ID,whoamI);if(whoamI!LSM6DSV_ID)while(1);復(fù)位傳感器該代碼首先對 LSM6DVE 進(jìn)行軟件復(fù)位。/* Restore default configuration */lsm6dsv_sw_por(dev_ctx);BDU設(shè)置在很多傳感器中數(shù)據(jù)通常被存儲在輸出寄存器中這些寄存器分為兩部分MSB和LSB。這兩部分共同表示一個完整的數(shù)據(jù)值。例如在一個加速度計中MSB和LSB可能共同表示一個加速度的測量值。連續(xù)更新模式BDU ‘0’在默認(rèn)模式下輸出寄存器的值會持續(xù)不斷地被更新。這意味著在你讀取MSB和LSB的時候寄存器中的數(shù)據(jù)可能會因為新的測量數(shù)據(jù)而更新。這可能導(dǎo)致一個問題當(dāng)你讀取MSB時如果寄存器更新了接下來讀取的LSB可能就是新的測量值的一部分而不是與MSB相對應(yīng)的值。這樣你得到的就是一個“拼湊”的數(shù)據(jù)它可能無法準(zhǔn)確代表任何實際的測量時刻。塊數(shù)據(jù)更新BDU模式BDU ‘1’當(dāng)激活BDU功能時輸出寄存器中的內(nèi)容不會在讀取MSB和LSB之間更新。這就意味著一旦開始讀取數(shù)據(jù)無論是先讀MSB還是LSB寄存器中的那一組數(shù)據(jù)就被“鎖定”直到兩部分都被讀取完畢。這樣可以確保你讀取的MSB和LSB是同一測量時刻的數(shù)據(jù)避免了讀取到代表不同采樣時刻的數(shù)據(jù)。簡而言之BDU位的作用是確保在讀取數(shù)據(jù)時輸出寄存器的內(nèi)容保持穩(wěn)定從而避免讀取到拼湊或錯誤的數(shù)據(jù)。這對于需要高精度和穩(wěn)定性的應(yīng)用尤為重要??梢韵駽TRL3_C(12h)的BDU寄存器寫入1進(jìn)行開啟。對應(yīng)的驅(qū)動程序,如下所示。/* Enable Block Data Update */LSM6DVE_block_data_update_set(dev_ctx,PROPERTY_ENABLE);配置輸出數(shù)據(jù)率與測量量程該代碼用于配置 LSM6DVE 加速度計和陀螺儀的基本采樣參數(shù)● 將加速度計和陀螺儀的輸出數(shù)據(jù)率均設(shè)置為 15 Hz即每秒產(chǎn)生約 15 組新的傳感器數(shù)據(jù)?!?將加速度計量程設(shè)置為 ±2 g適合檢測幅度較小的運動和姿態(tài)變化此時靈敏度為 0.061 mg/LSB?!?將陀螺儀量程設(shè)置為 ±2000 dps可測量較大的旋轉(zhuǎn)角速度此時靈敏度為 70 mdps/LSB。對應(yīng)程序如下所示。/* Set Output Data Rate. * Selected data rate have to be equal or greater with respect * with MLC data rate. */lsm6dsv_xl_data_rate_set(dev_ctx,LSM6DSV_ODR_AT_15Hz);lsm6dsv_gy_data_rate_set(dev_ctx,LSM6DSV_ODR_AT_15Hz);/* Set full scale */lsm6dsv_xl_full_scale_set(dev_ctx,LSM6DSV_2g);lsm6dsv_gy_full_scale_set(dev_ctx,LSM6DSV_2000dps);配置加速度計低通濾波器該代碼用于配置 LSM6DVE 加速度計的數(shù)字濾波鏈選擇 LPF1 LPF2 低通濾波路徑/* Configure filtering chain */filt_settling_mask.drdyPROPERTY_ENABLE;filt_settling_mask.irq_xlPROPERTY_ENABLE;filt_settling_mask.irq_gPROPERTY_ENABLE;lsm6dsv_filt_settling_mask_set(dev_ctx,filt_settling_mask);lsm6dsv_filt_gy_lp1_set(dev_ctx,PROPERTY_ENABLE);lsm6dsv_filt_gy_lp1_bandwidth_set(dev_ctx,LSM6DSV_GY_ULTRA_LIGHT);lsm6dsv_filt_xl_lp2_set(dev_ctx,PROPERTY_ENABLE);lsm6dsv_filt_xl_lp2_bandwidth_set(dev_ctx,LSM6DSV_XL_STRONG);輪詢讀取傳感器數(shù)據(jù)程序在主循環(huán)中持續(xù)檢測傳感器的數(shù)據(jù)狀態(tài)。當(dāng)加速度、角速度或溫度數(shù)據(jù)更新后讀取對應(yīng)的原始數(shù)據(jù)轉(zhuǎn)換為實際物理量并通過串口打印輸出。while(1){/* Read output only if new xl value is available */lsm6dsv_all_sources_get(dev_ctx,all_sources);if(all_sources.drdy_xl){/* Read acceleration field data */memset(data_raw_acceleration,0x00,3*sizeof(int16_t));lsm6dsv_acceleration_raw_get(dev_ctx,data_raw_acceleration);acceleration_mg[0]lsm6dsv_from_fs2_to_mg(data_raw_acceleration[0]);acceleration_mg[1]lsm6dsv_from_fs2_to_mg(data_raw_acceleration[1]);acceleration_mg[2]lsm6dsv_from_fs2_to_mg(data_raw_acceleration[2]);printf(Acceleration [mg]:%4.2f\t%4.2f\t%4.2f\r\n,acceleration_mg[0],acceleration_mg[1],acceleration_mg[2]);}if(all_sources.drdy_gy){/* Read angular rate field data */memset(data_raw_angular_rate,0x00,3*sizeof(int16_t));lsm6dsv_angular_rate_raw_get(dev_ctx,data_raw_angular_rate);angular_rate_mdps[0]lsm6dsv_from_fs2000_to_mdps(data_raw_angular_rate[0]);angular_rate_mdps[1]lsm6dsv_from_fs2000_to_mdps(data_raw_angular_rate[1]);angular_rate_mdps[2]lsm6dsv_from_fs2000_to_mdps(data_raw_angular_rate[2]);printf(Angular rate [mdps]:%4.2f\t%4.2f\t%4.2f\r\n,angular_rate_mdps[0],angular_rate_mdps[1],angular_rate_mdps[2]);}if(all_sources.drdy_temp){/* Read temperature data */memset(data_raw_temperature,0x00,sizeof(int16_t));lsm6dsv_temperature_raw_get(dev_ctx,data_raw_temperature);temperature_degClsm6dsv_from_lsb_to_celsius(data_raw_temperature);printf(Temperature [degC]:%6.2f\r\n,temperature_degC);}}演示