STM32C5开发LSM6DSOW(5)--运动唤醒检测
STM32C5开发LSM6DSOW .5--运动唤醒检测概述视频教学样品申请源码下载硬件准备参考程序串口配置IIC配置CS和SA0设置INT设置生成项目导入STM32CubeIDE设置工程编码串口 printf 重定向参考程序CMake设置头文件设置变量定义获取ID复位传感器BDU设置配置输出数据率与测量量程外部中断回调函数中断配置中断功能读取事件演示.5–运动唤醒检测 )概述本章介绍如何使用 STM32C542CCT6 驱动 LSM6DSOW 实现 Wake-up 运动检测。LSM6DSOW 内置可配置的 Wake-up 标准中断可利用 Low-G 加速度计对设备的动态运动进行检测并在运动幅度超过设定阈值后通过 INT1/INT2 输出中断信号。需要样片的可以加qun申请925643491 / 615061293 。视频教学样品申请https://www.wjx.top/vm/OhcKxJk.aspx#源码下载硬件准备首先需要准备一个开发板这里我准备的是自己绘制的开发板需要的可以进行申请。主控为STM32C542CC陀螺仪为LSM6DSOW磁力计为LIS2MDL。参考程序https://github.com/CoreMaker-lab/STM32C542_LSM6DOW_LIS2MDLhttps://gitee.com/CoreMaker/STM32C542_LSM6DOW_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设置确认 LSM6DSOW 的 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/lsm6dso-pid添加对应驱动程序。CMake设置在 CMakeLists.txt 中将 .c 加入编译并添加 -u _printf_float启用 printf() 浮点输出支持。target_sources(${CMAKE_PROJECT_NAME}PRIVATE lsm6dso_reg.c)target_link_options(${CMAKE_PROJECT_NAME}PUBLIC-u _printf_float)头文件设置添加头文件#includelsm6dso_reg.h初始换管脚由于需要向LSM6DSO_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/* * Wake-up threshold: * WU_INACT_THS_W 0 * 1 LSB 7.8125 mg * 2 15.625 mg * 4 31.25 mg * 8 62.5 mg */#defineWAKEUP_THRESHOLD4/* Private variables ---------------------------------------------------------*/staticuint8_twhoamI;/* 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);staticvoidplatform_delay(uint32_tms);staticstmdev_ctx_tdev_ctx;staticvolatileuint8_tthread_wake0;staticint32_tplatform_write(void*handle,uint8_treg,constuint8_t*bufp,uint16_tlen){if(HAL_I2C_MASTER_MemWrite((hal_i2c_handle_t*)handle,LSM6DSO_I2C_ADD_L,reg,HAL_I2C_MEM_ADDR_8BIT,bufp,len,1000)!HAL_OK)return-1;return0;}staticint32_tplatform_read(void*handle,uint8_treg,uint8_t*bufp,uint16_tlen){/* NOTE: the 0x80 read bit is only required on the SPI interface. * On I2C the register address must be sent as-is. */if(HAL_I2C_MASTER_MemRead((hal_i2c_handle_t*)handle,LSM6DSO_I2C_ADD_L,reg,HAL_I2C_MEM_ADDR_8BIT,bufp,len,1000)!HAL_OK)return-1;return0;}staticvoidplatform_delay(uint32_tms){HAL_Delay(ms);}在main() 中定义中断路由结构体和有关变量lsm6dso_pin_int1_route_tpin_int{0};uint8_trst0;获取ID我们可以向WHO_AM_I (0Fh)获取固定值判断是否为0x6c。对应的获取ID驱动程序,如下所示。/* Initialize mems driver interface */dev_ctx.write_regplatform_write;dev_ctx.read_regplatform_read;dev_ctx.mdelayplatform_delay;dev_ctx.handlemx_i2c1_i2c_gethandle();/* Wait sensor boot time */platform_delay(BOOT_TIME);/* Check device ID */lsm6dso_device_id_get(dev_ctx,whoamI);printf(LSM6DSO_ID0x%x,id0x%x\n,LSM6DSO_ID,whoamI);if(whoamI!LSM6DSO_ID)while(1);复位传感器该代码首先对传感器进行软件复位然后关闭I3C/* Perform device power-on-reset and wait for completion */lsm6dso_reset_set(dev_ctx,PROPERTY_ENABLE);do{lsm6dso_reset_get(dev_ctx,rst);}while(rst);/* Disable I3C interface (I2C bus) */lsm6dso_i3c_disable_set(dev_ctx,LSM6DSO_I3C_DISABLE);BDU设置在很多传感器中数据通常被存储在输出寄存器中这些寄存器分为两部分MSB和LSB。这两部分共同表示一个完整的数据值。例如在一个加速度计中MSB和LSB可能共同表示一个加速度的测量值。连续更新模式BDU ‘0’在默认模式下输出寄存器的值会持续不断地被更新。这意味着在你读取MSB和LSB的时候寄存器中的数据可能会因为新的测量数据而更新。这可能导致一个问题当你读取MSB时如果寄存器更新了接下来读取的LSB可能就是新的测量值的一部分而不是与MSB相对应的值。这样你得到的就是一个“拼凑”的数据它可能无法准确代表任何实际的测量时刻。块数据更新BDU模式BDU ‘1’当激活BDU功能时输出寄存器中的内容不会在读取MSB和LSB之间更新。这就意味着一旦开始读取数据无论是先读MSB还是LSB寄存器中的那一组数据就被“锁定”直到两部分都被读取完毕。这样可以确保你读取的MSB和LSB是同一测量时刻的数据避免了读取到代表不同采样时刻的数据。简而言之BDU位的作用是确保在读取数据时输出寄存器的内容保持稳定从而避免读取到拼凑或错误的数据。这对于需要高精度和稳定性的应用尤为重要。可以向CTRL3_C(12h)的BDU寄存器写入1进行开启。对应的驱动程序,如下所示。/* Enable Block Data Update */lsm6dso_block_data_update_set(dev_ctx,PROPERTY_ENABLE);配置输出数据率与测量量程该代码用于配置加速度计和陀螺仪的基本采样参数● 将加速度计和陀螺仪的输出数据率均设置为 417 Hz。● 将加速度计量程设置为 ±2 g。对应程序如下所示。/* * Set Low-G accelerometer. * * ODR 417 Hz * FS /-2 g */lsm6dso_xl_data_rate_set(dev_ctx,LSM6DSO_XL_ODR_417Hz);lsm6dso_xl_power_mode_set(dev_ctx,LSM6DSO_HIGH_PERFORMANCE_MD);lsm6dso_xl_full_scale_set(dev_ctx,LSM6DSO_2g);外部中断回调函数当 LSM6DSOW 传感器 的 INT1 引脚产生中断信号后MCU 进入 EXTI 中断处理流程并调用HAL_EXTI_TriggerCallback()。/** * brief EXTI trigger callback */voidHAL_EXTI_TriggerCallback(hal_exti_handle_t*hexti,hal_exti_trigger_ttrigger){if(HAL_EXTI_GetInstance(hexti)HAL_EXTI_GPIO_0){thread_wake1;}}中断配置对 LSM6DSOW 的中断输出进行配置将 INT1/INT2 设置为开漏输出并采用低电平有效方式以配合硬件上的外部上拉电阻和 STM32 PB0 的下降沿外部中断。/* * INT1/INT2: * open-drain active low */lsm6dso_pin_mode_set(dev_ctx,LSM6DSO_OPEN_DRAIN);lsm6dso_pin_polarity_set(dev_ctx,LSM6DSO_ACTIVE_LOW);中断功能开启 传感器 的基础事件中断功能并将中断设置为锁存模式。当运动事件发生后中断状态会保持避免由于中断脉冲过短导致 STM32 未能及时响应随后 MCU 可在主循环中读取中断源并完成对应事件处理。/* * Enable basic interrupts (wake-up) and latched mode. * Without this the event is detected but never driven on INT1. */lsm6dso_int_notification_set(dev_ctx,LSM6DSO_ALL_INT_LATCHED);为了提高 Wake-up 检测的稳定性代码中配置了加速度计快速稳定、滤波器稳定期间屏蔽中断触发以及 Wake-up 使用斜率/高通路径。/* * Enable XL Filter fast settling */lsm6dso_xl_fast_settling_set(dev_ctx,PROPERTY_ENABLE);/* * Mask interrupt trigger during * accelerometer filter settling. */lsm6dso_filter_settling_mask_set(dev_ctx,PROPERTY_ENABLE);/* * Use High-Pass filter for * Wake-up detection. */lsm6dso_xl_hp_path_internal_set(dev_ctx,LSM6DSO_USE_SLOPE);Wake-up 阈值通过 lsm6dso_wkup_ths_weight_set、lsm6dso_wkup_threshold_set 和 lsm6dso_wkup_dur_set 配置。代码中将权重设置为 LSM6DSO_LSb_FS_DIV_256在 FS ±2 g 时 1 LSB FS_XL / 256 7.8125 mgWAKEUP_THRESHOLD 4对应阈值 4 × 7.8125 mg 31.25 mg。wkup_dur 设置为 0。/* * Wake-up threshold configuration. * * wake_ths_w 1 (LSM6DSO_LSb_FS_DIV_256): * 1 LSB FS_XL / 256 2 g / 256 7.8125 mg * * threshold 4: * 4 x 7.8125 mg 31.25 mg */lsm6dso_wkup_ths_weight_set(dev_ctx,LSM6DSO_LSb_FS_DIV_256);lsm6dso_wkup_threshold_set(dev_ctx,WAKEUP_THRESHOLD);lsm6dso_wkup_dur_set(dev_ctx,0);将 Wake-up 运动事件映射至 INT1 引脚当检测到动态加速度超过设定阈值后MEMS 通过 INT1 产生中断通知 MCU。/* * Route Wake-up event to INT1 */pin_int.wake_upPROPERTY_ENABLE;lsm6dso_pin_int1_route_set(dev_ctx,pin_int);printf(Wake-up Motion Detection start...\r\n);printf(Threshold %d x 7.8125 mg\r\n,WAKEUP_THRESHOLD);读取事件当 INT1 检测到 Wake-up 运动事件后中断回调将 thread_wake 标志位置 1。主循环检测到该标志后读取传感器中断源并通过 wake_up 状态位判断是否发生运动事件如果检测有效则通过串口输出运动提示。由于程序采用锁存中断模式读取中断源的同时也可释放当前锁存状态为下一次运动检测做准备。while(1){if(thread_wake){lsm6dso_all_sources_tstatus{0};thread_wake0;/* Read status so the latched interrupt is cleared * and INT1 can be asserted again on the next event. */lsm6dso_all_sources_get(dev_ctx,status);printf(Motion detected\r\n);}}演示移动或晃动开发板使动态加速度满足运动唤醒条件后串口输出 Motion detected。本例只提示运动事件不输出进入静止状态的信息。

相关新闻

React Native鸿蒙适配:跨平台构建与目录解析

React Native鸿蒙适配:跨平台构建与目录解析

最近几年,跨端开发的赛道一直没有消停过。Flutter 在持续发力,KMP 也在不断扩张地盘,但 React Native 这个老牌选手,依然有着庞大的社区存量和生态积累。而随着 OpenHarmony 生态的逐步成熟,一个很现实的问题摆在很多团…

2026/10/15 7:49:01 阅读更多 →
AI辅助开发实战:三周用WorkBuddy+Supabase上线Android App

AI辅助开发实战:三周用WorkBuddy+Supabase上线Android App

1. 为什么我选择 WorkBuddy 来搭一个真正能上线的 App去年年底我接了个私活,帮一个做线下活动策划的团队做内部工具。需求不复杂:活动排期、人员签到、物料清单、简单的数据看板。但对方提了一个硬性要求——必须是一个能装到手机上的 App,而…

2026/10/15 7:49:01 阅读更多 →
SpringBoot+Vue智能调度系统开发实践

SpringBoot+Vue智能调度系统开发实践

1. 项目背景与核心价值基层人员调度一直是各类服务型机构面临的典型管理难题。传统的人工排班方式存在响应慢、效率低、资源分配不均等问题。去年参与某社区服务中心信息化改造时,我亲眼目睹工作人员每天要花2个多小时手工处理排班表,还经常出现岗位冲突…

2026/10/15 7:49:01 阅读更多 →

最新新闻

从画图到设计:用文本化DSL把架构图变成可维护的工程资产

从画图到设计:用文本化DSL把架构图变成可维护的工程资产

平时我见得最多的“图”,不是最终文档里那张漂亮的架构图,而是评审会上被临时画在白板上的方框加箭头。主讲人一边画一边改,台下的人一边看一边猜。等会议结束,没人记得箭头谁指向谁,只记得“好像讲了一个方案”。后来…

2026/10/15 8:25:33 阅读更多 →
t3code赛事编码协议:从计时数据到成绩榜单的自动化方案

t3code赛事编码协议:从计时数据到成绩榜单的自动化方案

如果你跟我一样,经常被各种赛事计时表、Excel 成绩单、手动排名搞到半夜,那你一定要试试 t3code 这套思路。t3code 最开始只是我给一个周末赛车活动写的三行脚本,后来慢慢变成了一套三段式赛事编码协议:练习、排位、正赛三段&…

2026/10/15 8:25:33 阅读更多 →
SylixOS应用开发指南:线程模型、同步机制与调试实践

SylixOS应用开发指南:线程模型、同步机制与调试实践

简介:《SylixOS应用开发手册1》是一份面向具备C语言基础的程序员的实时嵌入式操作系统开发指南,系统讲解SylixOS应用程序设计接口,适用于航空航天、工业自动化、通信、新能源等场景。压缩包内共1个pdf文件,大小14.95MB&#xff0c…

2026/10/15 8:25:33 阅读更多 →
多协议网络库的架构设计与核心实现:从Reactor线程模型到协议解析

多协议网络库的架构设计与核心实现:从Reactor线程模型到协议解析

1. 为什么需要多协议网络库大概两年前,我们团队接手了一个典型的“什么都要接”的后台系统:对外要提供HTTP接口,方便前端和第三方系统调用;要和一批长期在线的硬件设备保持TCP长连接,并且随时可能下发指令;…

2026/10/15 8:25:33 阅读更多 →
T3 Stack全栈实战:构建类型安全的代码片段管理应用

T3 Stack全栈实战:构建类型安全的代码片段管理应用

如果你正在找一份能直接上手、不用绕弯子的全栈项目教程,那么基于 T3 Stack 打造的t3code应该能对上你的胃口。这个项目本质上是一个代码片段分享与管理系统,开发者可以注册登录,把自己常用的代码块按语言分类保存,支持标签检索、…

2026/10/15 8:25:33 阅读更多 →
多模态AI视频搜索实战:从250分钟到2分钟的工程化落地

多模态AI视频搜索实战:从250分钟到2分钟的工程化落地

1. 项目背景与核心痛点拆解1.1 250分钟到底卡在哪里视频搜索这件事,没做过的人会觉得不就是搜个关键词吗。但真正处理过大规模视频素材库的从业者都清楚,传统视频检索的流程有多笨重。Cond Nast 作为一家拥有海量视频内容的媒体集团,旗下品牌…

2026/10/15 8:24:32 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →