首页 / 资讯中心 / 文章详情

STM32C5开发LSM6DSK320X(6)--倾斜度检测

STM32C5开发LSM6DSK320X(6)--倾斜度检测 ★ FEATURED ARTICLE
STM32C5开发LSM6DSK320X .6--倾斜度检测概述视频教学样品申请源码下载硬件准备参考程序串口配置IIC配置CS和SA0设置INT设置生成项目导入STM32CubeIDE设置工程编码串口 printf 重定向参考程序CMake设置驱动接口与中断回调配置传感器接口初始化与设备检查加速度计与中断输出配置使能倾斜检测切换到嵌入式功能寄存器页配置嵌入式功能中断锁存初始化 Tilt 算法恢复主寄存器页将倾斜事件路由到 INT1主循环.6–倾斜度检测)概述IMU内置倾斜检测Tilt功能通过加速度计感知设备姿态变化并在满足内部算法判定条件时产生倾斜事件。例如将设备放在裤子前口袋中从坐姿变为站姿或从站姿变为坐姿可触发检测。 Tilt 输出的是倾斜变化事件不直接提供具体的倾斜角度。视频教学样品申请源码下载硬件准备首先需要准备一个开发板这里我准备的是自己绘制的开发板需要的可以进行申请。主控为STM32C542CCT6陀螺仪为LSM6DSK320X磁力计为LIS2MDL。参考程序https://github.com/CoreMaker-lab/STM32C542_LSM6DSK320X_LIS2MDLhttps://gitee.com/CoreMaker/STM32C542_LSM6DSK320X_LIS2MDL串口配置查看原理图PA9和PA10设置为开发板的串口。选择 Connectivity → USART1设置为 Async 异步模式波特率 115200、8 位数据、无校验、1 位停止位启用收发模式。串口的TX、RX 分别选择 PA9、PA10均设置为复用模式Alternate、无上下拉、推挽输出速度选择 Low。IIC配置STM32C542CCT6通过扩展接口与传感器模块连接其中PB6作为I²C时钟线SCLPB7作为I²C数据线SDA首先在 STM32CubeMX2 中进入 Peripherals 外设配置页面在 Connectivity 分类中选择 I2C1并将 I2C1 外设使能。如图所示本实验的 I2C1 配置步骤如下点击左侧 Peripherals 外设配置入口在 Connectivity 分类中选择 I2C1将 I2C1 Mode 设置为 I2C并确认 I2C1 显示为 ActiveSpeed frequency 设置为 Fast mode - 400 kHz确认 I2C1 的 GPIO 引脚映射SCL 为 PB6SDA 为 PB7CS和SA0设置确认I2C 模式选择和地址选择CS 需要处于 I2C 模式对应电平SA0 需要固定为高电平或低电平将 PA1 和 PB2 配置为普通 GPIO。在 Pinout 页面将 PA1、PB2 设置为 GPIO → Configured分别用于 SA0I²C 地址选择和 CS通信接口选择。进入 System → GPIO将 PA1、PB2 设置为推挽输出、无上下拉、低速由程序控制输出电平。板载 LIS2MDL 的 CS 引脚连接 PA6。在 Pinout 页面将 PA6 设置为 GPIO → Configured。进入 System → GPIO将 PA6 命名为 CS2设置为推挽输出、无上下拉、低速由程序控制输出电平。INT设置IMU 的 INT1Pin4连接 STM32C542 的 PB0用于接收陀螺仪数据就绪中断。将 PB0 配置为输入、无上下拉开启 EXTI0选择下降沿触发Falling edge使能中断及 IRQ Handler 生成。生成项目修改配置后左下角会提示 Click to save需要先保存当前工程配置点击左侧 Project settings进入工程生成设置页面在 IDE Project Generation 中选择工程格式和工具链本例选择 CMake GCC然后点击 Generate IDE project 生成工程导入STM32CubeIDE打开 STM32CubeIDE选择 File → Import导入 STM32CubeMX2 生成的 CMake 工程。展开 Import STM32 Project选择 STM32 CMake Project点击 Next进入工程路径选择页面。Project name填写导入到 STM32CubeIDE 中显示的工程名称Source directory选择 STM32CubeMX2 生成的 CMake 工程目录点击 Next继续完成工程导入Toolchain选择 MCU ARM GCC表示使用 ARM GCC 工具链进行编译MCU确认芯片型号为 STM32C542CCTx与前面 STM32CubeMX2 中选择的 MCU 保持一致CPU/Core确认内核为 Cortex-M33Core 为 0点击 Finish完成 CMake 工程导入设置工程编码在 Project Explorer 中选中工程点击 Project → Properties。选择 Resource将 Text file encoding 设置为 Other → GBK点击 Apply and Close 保存。串口 printf 重定向在 main.c 中添加以下头文件并在 main() 前实现 _write()将 printf() 输出重定向到 USART1用于打印 MEMS 数据和调试信息。#includemx_usart1.h#includestdio.h#includestring.hint_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/lsm6dsv320x-pid添加对应驱动程序。CMake设置在 CMakeLists.txt 中将 .c 加入编译并添加 -u _printf_float启用 printf() 浮点输出支持。target_sources(${CMAKE_PROJECT_NAME}PRIVATE lsm6dsk320x_reg.c)target_link_options(${CMAKE_PROJECT_NAME}PUBLIC-u _printf_float)驱动接口与中断回调配置在 main.c 中引入 .h并定义启动等待时间 BOOT_TIME 为 10 ms、读取ID。变量 whoamI 用于保存读取到的设备 IDdev_ctx 用于绑定底层通信接口thread_wake 用于标记中断事件。声明 platform_write()、platform_read() 和 platform_delay()分别实现寄存器写入、读取及延时。同时通过 _write() 将 printf() 重定向至 USART1方便输出检测结果。在外部中断回调 HAL_EXTI_TriggerCallback() 中判断中断是否来自 GPIO EXTI0若匹配则将 thread_wake 置为 1。主循环随后读取传感器状态判断是否发生事件。回调中仅设置标志位寄存器读取和串口输出均在主循环中完成。#includelsm6dsk320x_reg.h#defineBOOT_TIME10U#defineBOARD_EXPECTED_ID0x75Ustaticuint8_twhoamI;staticstmdev_ctx_tdev_ctx;staticvolatileuint8_tthread_wake0;staticint32_tplatform_write(void*handle,uint8_treg,constuint8_t*bufp,uint16_tlen);staticint32_tplatform_read(void*handle,uint8_treg,uint8_t*bufp,uint16_tlen);staticvoidplatform_delay(uint32_tms);/** * brief EXTI trigger callback */voidHAL_EXTI_TriggerCallback(hal_exti_handle_t*hexti,hal_exti_trigger_ttrigger){(void)trigger;if(HAL_EXTI_GetInstance(hexti)HAL_EXTI_GPIO_0){thread_wake1;}}传感器接口初始化与设备检查系统初始化完成后设置 CS1、CS2 为高电平SA0 为低电平并将寄存器读写函数、延时函数及 I²C1 句柄绑定到 dev_ctx建立传感器通信接口。等待 10 ms 后读取并通过串口打印设备 ID。当 ID 不匹配 时程序停止运行检查通过后执行软件复位并再次等待 10 ms随后使能 BDU块数据更新为后续检测配置做好准备。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);lsm6dsk320x_if_cfg_tif_cfg{0};lsm6dsk320x_page_rw_tpage_rw{0};lsm6dsk320x_emb_func_init_a_temb_init{0};lsm6dsk320x_pin_int_route_tpin_int{0};/* Initialize mems driver interface */dev_ctx.write_regplatform_write;dev_ctx.read_regplatform_read;dev_ctx.mdelayplatform_delay;dev_ctx.handlemx_i2c1_i2c_gethandle();platform_delay(BOOT_TIME);/* Check device ID */printf(LSM6DSK320X_ID0x%x,id0x%x\n,0x75,whoamI);if(whoamI!0x75)while(1);/* Reset Device*/lsm6dsk320x_sw_reset(dev_ctx);platform_delay(BOOT_TIME);/* Enable Block Data Update */lsm6dsk320x_block_data_update_set(dev_ctx,PROPERTY_ENABLE);加速度计与中断输出配置将低量程加速度计设置为高性能模式输出数据率ODR为 480 Hz量程为 ±2 g为检测提供加速度数据。随后读取 IF_CFG 寄存器将 pp_od 和 h_lactive 均设置为 1再写回寄存器使中断引脚采用开漏输出、低电平有效方式。对应的 MCU 输入引脚需配置上拉并使用下降沿触发外部中断。/* Low-G accelerometer: 480 Hz, /-2 g. */lsm6dsk320x_xl_setup(dev_ctx,LSM6DSK320X_ODR_AT_480Hz,LSM6DSK320X_XL_HIGH_PERFORMANCE_MD);lsm6dsk320x_xl_full_scale_set(dev_ctx,LSM6DSK320X_2g);/* INT1: open-drain active low. */lsm6dsk320x_read_reg(dev_ctx,LSM6DSK320X_IF_CFG,(uint8_t*)if_cfg,1);if_cfg.pp_od1;if_cfg.h_lactive1;lsm6dsk320x_write_reg(dev_ctx,LSM6DSK320X_IF_CFG,(uint8_t*)if_cfg,1);使能倾斜检测Tilt 利用加速度计检测倾斜姿态变化。例如手机放在裤子前口袋中用户由坐姿变为站姿或由站姿变为坐姿可产生倾斜事件。这里检测的是倾斜变化事件不直接输出具体角度。 本条语句仅使能算法中断输出还需要后续路由配置。这一步将嵌入式功能寄存器 EMB_FUNC_EN_A04h中的 TILT_EN 位置为 1启用芯片内部的倾斜检测算法。/* Enable Tilt detection. */lsm6dsk320x_tilt_mode_set(dev_ctx,PROPERTY_ENABLE);切换到嵌入式功能寄存器页传感器的寄存器分为不同的寄存器页。接下来要访问的 PAGE_RW 和 EMB_FUNC_INIT_A 均属于嵌入式功能寄存器页因此需要先切换访问区域。该操作对应 FUNC_CFG_ACCESS01h中的 EMB_FUNC_REG_ACCESS 位。/* Switch to embedded-function register bank. */lsm6dsk320x_mem_bank_set(dev_ctx,LSM6DSK320X_EMBED_FUNC_MEM_BANK);配置嵌入式功能中断锁存将 PAGE_RW17h中的 EMB_FUNC_LIR 位置为 1同时保留寄存器中的其他配置。开启锁存后倾斜事件产生的中断请求会被保留便于 MCU 在主循环中读取处理。结合前面设置的低电平有效模式事件触发后 INT1 进入有效低电平状态。在默认 INT_ACK_MASK.IACK_MASK4 0 的情况下读取 EMB_FUNC_STATUS_MAINPAGE 或 EMB_FUNC_STATUS会清除对应的 Tilt 锁存状态。如果没有其他中断源仍处于有效状态INT1 随后释放。/* Latch embedded-function interrupts. */lsm6dsk320x_read_reg(dev_ctx,LSM6DSK320X_PAGE_RW,(uint8_t*)page_rw,1);page_rw.emb_func_lir1;lsm6dsk320x_write_reg(dev_ctx,LSM6DSK320X_PAGE_RW,(uint8_t*)page_rw,1);初始化 Tilt 算法这一步向 EMB_FUNC_INIT_A66h寄存器的 TILT_INIT 位写入 1发出倾斜检测算法初始化请求。这不是整颗芯片的软件复位也不是将当前姿态标定为 0°。 手册将该位定义为算法初始化请求没有将其定义为用户倾角零点校准。/* Initialize Tilt algorithm. */emb_init.tilt_init1;lsm6dsk320x_write_reg(dev_ctx,LSM6DSK320X_EMB_FUNC_INIT_A,(uint8_t*)emb_init,1);恢复主寄存器页嵌入式寄存器配置完成后恢复主寄存器页为后续中断路由和状态读取做好准备。/* Restore main register bank. */lsm6dsk320x_mem_bank_set(dev_ctx,LSM6DSK320X_MAIN_MEM_BANK);将倾斜事件路由到 INT1先设置软件结构体随后调用驱动接口将配置写入芯片使倾斜事件能够通过 INT1 引脚通知 MCU。/* Route Tilt event to INT1. */pin_int.tiltPROPERTY_ENABLE;lsm6dsk320x_pin_int1_route_embedded_set(dev_ctx,pin_int);主循环主循环持续检查软件标志 thread_wake。当标志为 1 时先将其清零再读取 EMB_FUNC_STATUS_MAINPAGE 寄存器获取嵌入式功能的中断状态。在已开启锁存且中断确认屏蔽保持默认配置的情况下读取该寄存器会清除对应的锁存事件。while(1){if(thread_wake){lsm6dsk320x_emb_func_status_mainpage_tstatus{0};thread_wake0;/* Read Tilt status and clear the latched event. */if(lsm6dsk320x_read_reg(dev_ctx,LSM6DSK320X_EMB_FUNC_STATUS_MAINPAGE,(uint8_t*)status,1)!0){thread_wake1;platform_delay(100);continue;}if(status.is_tilt){printf(Tilt detected\r\n);}}}演示改变开发板的倾斜姿态当满足芯片内部 Tilt 算法的判定条件时串口输出 Tilt detected。
阅读完成 · 觉得有帮助?
咨询建站