MSPM03507驱动MPU6050:嵌入式运动检测与姿态解算实战 这次我们来看一个嵌入式开发中的实用项目——MSPM03507天猛星MPU6050驱动。对于需要运动检测和姿态控制的嵌入式应用来说MPU6050是一个性价比极高的选择而德州仪器的MSPM03507微控制器则为这类应用提供了强大的处理能力。MPU6050是一款集成了3轴加速度计和3轴陀螺仪的6轴运动跟踪传感器能够检测加速度、旋转和温度变化。它广泛应用于机器人、游戏控制器、无人机等需要运动感知的设备中。MSPM03507作为TI的MSPM0系列微控制器具有低功耗、高性能的特点特别适合物联网和嵌入式传感应用。本文将重点介绍如何在MSPM03507平台上实现MPU6050的完整驱动包括I2C通信配置、传感器初始化、数据读取和姿态解算等关键环节。通过实际的代码示例和测试验证帮助读者快速掌握这一技术组合的实际应用。1. 核心能力速览能力项说明传感器类型6轴运动跟踪3轴加速度计 3轴陀螺仪通信接口I2C标准接口支持400kHz快速模式测量范围加速度计±2g/±4g/±8g/±16g陀螺仪±250°/s/±500°/s/±1000°/s/±2000°/s处理器平台TI MSPM03507微控制器开发环境Code Composer Studio或IAR Embedded Workbench主要功能运动检测、姿态解算、温度监测适用场景机器人控制、无人机导航、运动追踪设备2. MPU6050传感器工作原理MPU6050传感器模块包含两个核心部件3轴加速度计和3轴陀螺仪它们基于不同的物理原理工作共同实现完整的运动检测功能。2.1 3轴加速度计工作原理加速度计基于压电效应原理工作。可以想象一个立方体盒子内部有一个小球盒子的六个壁面都由压电晶体材料制成。当盒子倾斜时由于重力作用小球会向倾斜方向移动撞击对应的壁面产生微小的压电电流。MPU6050有三对相对的压电壁面分别对应三维空间的X、Y、Z轴。通过检测各轴产生的电流大小和方向就能确定倾斜的角度和幅度。在静止状态下Z轴加速度约为1g重力加速度X、Y轴加速度为0。当传感器倾斜或处于失重/超重状态时相应的读数会发生变化。加速度计支持四种可编程选择的测量范围±2g、±4g、±8g和±16g默认范围为±2g。原始数据范围为-32768到32767通过以下公式转换为实际加速度值加速度 (加速度计轴原始数据 / 65536 × 全量程加速度范围) g以X轴为例当原始数据为16384量程选择±2g时 X轴加速度 (16384 / 65536 × 4) g 1g2.2 3轴陀螺仪工作原理陀螺仪基于科里奥利加速度原理工作。想象一个持续前后振动的音叉结构由压电晶体固定。当尝试倾斜这个装置时振动音叉的惯性会使晶体受到倾斜方向的力从而产生压电电流。陀螺仪同样支持四种测量范围±250°/s、±500°/s、±1000°/s和±2000°/s。角速度的计算公式与加速度计类似角速度 (陀螺仪轴原始数据 / 65536 × 全量程陀螺仪范围) °/s以X轴为例当原始数据为16384量程选择±250°/s时 X轴角速度 (16384 / 65536 × 500) °/s 125°/s3. 硬件连接与电路设计MSPM03507与MPU6050的连接基于I2C通信协议需要正确配置硬件引脚连接和电源电路。3.1 硬件组件清单MSPM03507开发板 × 1MPU6050传感器模块 × 1杜邦线若干面包板或PCB底板3.3V稳压电源3.2 电路连接方案MSPM03507引脚 MPU6050引脚 功能描述 ----------- ----------- -------- 3.3V VCC 电源正极 GND GND 电源地 PA10SCL SCL I2C时钟线 PA11SDA SDA I2C数据线MPU6050的AD0引脚用于设置I2C从机地址接地时地址为0x68接高电平时地址为0x69。在大多数应用中建议将AD0接地使用默认地址。3.3 电源设计考虑MSPM03507工作电压为3.3VMPU6050也支持3.3V供电。需要确保电源能够提供足够的电流特别是在传感器启动和数据采集峰值期间。建议在VCC和GND之间添加100nF去耦电容以提高系统稳定性。4. 软件开发环境配置在开始编写驱动代码前需要配置合适的开发环境和必要的软件库。4.1 开发工具准备推荐使用德州仪器的Code Composer StudioCCS作为主要开发环境或者IAR Embedded Workbench。CCS提供了完整的MSPM0系列支持包和丰富的调试功能。安装步骤如下下载并安装Code Composer Studio最新版本安装MSPM0系列器件支持包导入或创建新的MSPM03507工程模板4.2 必要的软件库对于MPU6050驱动开发需要配置以下基础库// MSPM03507标准外设库 #include ti_msp_dl_config.h #include ti_msp_dl_types.h // I2C通信库 #include driverlib/i2c.h // 数学库用于姿态解算 #include math.h4.3 工程配置要点在CCS中创建新工程时需要正确配置器件选择MSPM03507编译器版本TI ARM Clang Compiler运行时环境选择基本的驱动程序库优化级别根据需求选择-O0调试或-O2发布5. I2C通信基础配置MPU6050通过I2C接口与MSPM03507通信需要正确初始化I2C外设并实现基本的读写函数。5.1 I2C外设初始化// I2C初始化配置 void I2C_Init(void) { // 启用I2C外设时钟 DL_SYSCTL_enableSYSCTLPeripheral(SYSCTL_PERIPH_CLK_I2C0); // 配置I2C引脚功能 DL_GPIO_setMSPM0GPortPinFunction(GPIO_PA10_I2C0_SCL); DL_GPIO_setMSPM0GPortPinFunction(GPIO_PA11_I2C0_SDA); // I2C控制器配置 DL_I2C_initController(I2C0_INST, I2C0_CLOCK_FREQ, I2C_CLOCK_FREQ_400K, I2C0_DUTY_CYCLE); // 启用I2C控制器 DL_I2C_enableController(I2C0_INST); }5.2 I2C基本读写函数// I2C写单个字节到指定寄存器 uint8_t MPU6050_Write_Byte(uint8_t reg_addr, uint8_t data) { uint8_t status; // 启动传输 DL_I2C_setSlaveAddress(I2C0_INST, MPU6050_ADDRESS); DL_I2C_setTransmitMode(I2C0_INST); DL_I2C_setMasterMode(I2C0_INST); // 发送寄存器地址和数据 DL_I2C_transmitDataByte(I2C0_INST, reg_addr); DL_I2C_transmitDataByte(I2C0_INST, data); // 等待传输完成 while(DL_I2C_isBusBusy(I2C0_INST)); status DL_I2C_getControllerStatus(I2C0_INST); return (status I2C_STATUS_SUCCESS); } // I2C从指定寄存器读取单个字节 uint8_t MPU6050_Read_Byte(uint8_t reg_addr, uint8_t *data) { uint8_t status; // 先写入要读取的寄存器地址 DL_I2C_setSlaveAddress(I2C0_INST, MPU6050_ADDRESS); DL_I2C_setTransmitMode(I2C0_INST); DL_I2C_setMasterMode(I2C0_INST); DL_I2C_transmitDataByte(I2C0_INST, reg_addr); // 重新启动为接收模式 DL_I2C_setReceiveMode(I2C0_INST); DL_I2C_setMasterMode(I2C0_INST); // 读取数据 *data DL_I2C_receiveDataByte(I2C0_INST); while(DL_I2C_isBusBusy(I2C0_INST)); status DL_I2C_getControllerStatus(I2C0_INST); return (status I2C_STATUS_SUCCESS); }6. MPU6050驱动实现完整的MPU6050驱动包括传感器初始化、配置设置、数据读取和校准等功能。6.1 传感器初始化函数// MPU6050初始化 uint8_t MPU6050_Init(void) { uint8_t check, data; // 检查设备ID MPU6050_Read_Byte(MPU6050_WHO_AM_I, check); if(check ! 0x68) // 设备ID应为0x68 { return 0; // 初始化失败 } // 唤醒MPU6050退出睡眠模式 data 0x00; MPU6050_Write_Byte(MPU6050_PWR_MGMT_1, data); DL_DelayMS(100); // 设置加速度计量程为±8g MPU6050_Write_Byte(MPU6050_ACCEL_CONFIG, MPU6050_ACCEL_FS_8); // 设置陀螺仪量程为±500°/s MPU6050_Write_Byte(MPU6050_GYRO_CONFIG, MPU6050_GYRO_FS_500); // 配置低通滤波器带宽21Hz MPU6050_Write_Byte(MPU6050_CONFIG, MPU6050_DLPF_BW_21); return 1; // 初始化成功 }6.2 传感器数据读取函数// 读取原始加速度数据 void MPU6050_Read_Accel(int16_t* accel_x, int16_t* accel_y, int16_t* accel_z) { uint8_t data[6]; // 读取加速度计数据寄存器6个字节 MPU6050_Read_Bytes(MPU6050_ACCEL_XOUT_H, data, 6); *accel_x (int16_t)((data[0] 8) | data[1]); *accel_y (int16_t)((data[2] 8) | data[3]); *accel_z (int16_t)((data[4] 8) | data[5]); } // 读取原始陀螺仪数据 void MPU6050_Read_Gyro(int16_t* gyro_x, int16_t* gyro_y, int16_t* gyro_z) { uint8_t data[6]; // 读取陀螺仪数据寄存器6个字节 MPU6050_Read_Bytes(MPU6050_GYRO_XOUT_H, data, 6); *gyro_x (int16_t)((data[0] 8) | data[1]); *gyro_y (int16_t)((data[2] 8) | data[3]); *gyro_z (int16_t)((data[4] 8) | data[5]); } // 读取温度数据 float MPU6050_Read_Temperature(void) { uint8_t data[2]; int16_t temp_raw; float temperature; MPU6050_Read_Bytes(MPU6050_TEMP_OUT_H, data, 2); temp_raw (int16_t)((data[0] 8) | data[1]); // 温度转换公式TEMP_degC (TEMP_OUT / 340) 36.53 temperature (float)temp_raw / 340.0 36.53; return temperature; }6.3 多字节读取函数实现// 从指定寄存器连续读取多个字节 uint8_t MPU6050_Read_Bytes(uint8_t reg_addr, uint8_t* data, uint8_t length) { uint8_t i, status; // 先写入要读取的起始寄存器地址 DL_I2C_setSlaveAddress(I2C0_INST, MPU6050_ADDRESS); DL_I2C_setTransmitMode(I2C0_INST); DL_I2C_setMasterMode(I2C0_INST); DL_I2C_transmitDataByte(I2C0_INST, reg_addr); // 重新启动为接收模式 DL_I2C_setReceiveMode(I2C0_INST); DL_I2C_setMasterMode(I2C0_INST); // 连续读取数据 for(i 0; i length; i) { if(i length - 1) { // 最后一个字节发送NACK DL_I2C_sendNACK(I2C0_INST); } data[i] DL_I2C_receiveDataByte(I2C0_INST); } while(DL_I2C_isBusBusy(I2C0_INST)); status DL_I2C_getControllerStatus(I2C0_INST); return (status I2C_STATUS_SUCCESS); }7. 传感器校准与数据处理原始传感器数据通常包含偏差和噪声需要进行校准和滤波处理才能获得准确的运动信息。7.1 加速度计和陀螺仪校准// 传感器校准数据结构 typedef struct { int16_t accel_offset[3]; int16_t gyro_offset[3]; uint16_t sample_count; } MPU6050_Calibration_t; // 自动校准函数 void MPU6050_Auto_Calibrate(MPU6050_Calibration_t* calib) { int32_t accel_sum[3] {0, 0, 0}; int32_t gyro_sum[3] {0, 0, 0}; int16_t accel_raw[3], gyro_raw[3]; uint16_t i; // 采集多组数据进行平均 for(i 0; i calib-sample_count; i) { MPU6050_Read_Accel(accel_raw[0], accel_raw[1], accel_raw[2]); MPU6050_Read_Gyro(gyro_raw[0], gyro_raw[1], gyro_raw[2]); for(int j 0; j 3; j) { accel_sum[j] accel_raw[j]; gyro_sum[j] gyro_raw[j]; } DL_DelayMS(10); } // 计算偏移量 for(i 0; i 3; i) { calib-accel_offset[i] (int16_t)(accel_sum[i] / calib-sample_count); calib-gyro_offset[i] (int16_t)(gyro_sum[i] / calib-sample_count); } } // 应用校准数据 void MPU6050_Apply_Calibration(int16_t* raw_data, const int16_t* offset) { for(int i 0; i 3; i) { raw_data[i] - offset[i]; } }7.2 数据滤波处理// 简单移动平均滤波 typedef struct { int16_t buffer[3][8]; // 3轴8点缓冲 uint8_t index; } MPU6050_Filter_t; void MPU6050_Filter_Init(MPU6050_Filter_t* filter) { memset(filter, 0, sizeof(MPU6050_Filter_t)); } void MPU6050_Apply_Filter(MPU6050_Filter_t* filter, int16_t* raw_data) { int32_t sum[3] {0, 0, 0}; // 更新缓冲区 for(int i 0; i 3; i) { filter-buffer[i][filter-index] raw_data[i]; } filter-index (filter-index 1) % 8; // 计算移动平均 for(int i 0; i 3; i) { for(int j 0; j 8; j) { sum[i] filter-buffer[i][j]; } raw_data[i] (int16_t)(sum[i] / 8); } }8. 姿态解算算法实现基于MPU6050的加速度计和陀螺仪数据可以实现基本的姿态解算获取设备的俯仰角、横滚角和偏航角。8.1 互补滤波算法// 姿态角数据结构 typedef struct { float pitch; // 俯仰角 float roll; // 横滚角 float yaw; // 偏航角 } MPU6050_Attitude_t; // 互补滤波姿态解算 void MPU6050_Complementary_Filter(MPU6050_Attitude_t* attitude, const int16_t* accel, const int16_t* gyro, float dt) { static float pitch_acc, roll_acc; static float pitch_gyro 0, roll_gyro 0, yaw_gyro 0; const float alpha 0.98f; // 互补滤波系数 // 从加速度计计算俯仰和横滚角单位弧度 pitch_acc atan2f(accel[0], sqrtf(accel[1]*accel[1] accel[2]*accel[2])); roll_acc atan2f(accel[1], sqrtf(accel[0]*accel[0] accel[2]*accel[2])); // 从陀螺仪计算角度变化转换为弧度/秒然后积分 pitch_gyro (gyro[1] / 65.5f) * (3.14159f / 180.0f) * dt; // 65.5 LSB/(°/s) roll_gyro (gyro[0] / 65.5f) * (3.14159f / 180.0f) * dt; yaw_gyro (gyro[2] / 65.5f) * (3.14159f / 180.0f) * dt; // 互补滤波融合 attitude-pitch alpha * (attitude-pitch pitch_gyro) (1 - alpha) * pitch_acc; attitude-roll alpha * (attitude-roll roll_gyro) (1 - alpha) * roll_acc; attitude-yaw yaw_gyro; // 加速度计无法测量偏航角 // 转换为角度制 attitude-pitch * (180.0f / 3.14159f); attitude-roll * (180.0f / 3.14159f); attitude-yaw * (180.0f / 3.14159f); }8.2 DMP数字运动处理器使用MPU6050内置了DMP硬件可以自动完成姿态解算减轻主处理器负担。以下是DMP的基本使用方法// DMP初始化 uint8_t MPU6050_DMP_Init(void) { uint8_t data; // 唤醒MPU6050 data 0x00; MPU6050_Write_Byte(MPU6050_PWR_MGMT_1, data); DL_DelayMS(100); // 启用DMP功能 data 0x02; // 启用DMP MPU6050_Write_Byte(MPU6050_USER_CTRL, data); // 配置DMP参数 // ... DMP具体配置代码 return 1; } // 读取DMP解算的姿态数据 uint8_t MPU6050_DMP_Read_Quaternion(float* q) { uint8_t fifo_buffer[16]; uint16_t fifo_count; // 读取FIFO计数 MPU6050_Read_Bytes(MPU6050_FIFO_COUNTH, (uint8_t*)fifo_count, 2); if(fifo_count 16) { // 读取四元数数据 MPU6050_Read_Bytes(MPU6050_FIFO_R_W, fifo_buffer, 16); // 解析四元数大端格式 q[0] (float)((int16_t)((fifo_buffer[0] 8) | fifo_buffer[1])) / 16384.0f; q[1] (float)((int16_t)((fifo_buffer[4] 8) | fifo_buffer[5])) / 16384.0f; q[2] (float)((int16_t)((fifo_buffer[8] 8) | fifo_buffer[9])) / 16384.0f; q[3] (float)((int16_t)((fifo_buffer[12] 8) | fifo_buffer[13])) / 16384.0f; return 1; } return 0; }9. 完整应用示例下面提供一个完整的MPU6050驱动应用示例展示如何在MSPM03507上实现运动检测功能。9.1 主程序框架#include ti_msp_dl_config.h #include stdio.h // MPU6050相关变量定义 MPU6050_Calibration_t sensor_calib {0}; MPU6050_Filter_t sensor_filter; MPU6050_Attitude_t current_attitude {0}; int main(void) { // 系统初始化 SYSCFG_DL_init(); // I2C初始化 I2C_Init(); // MPU6050初始化 if(!MPU6050_Init()) { // 初始化失败处理 while(1); } // 传感器校准 sensor_calib.sample_count 100; MPU6050_Auto_Calibrate(sensor_calib); // 滤波器初始化 MPU6050_Filter_Init(sensor_filter); // 主循环 while(1) { int16_t accel_raw[3], gyro_raw[3]; float temperature; // 读取传感器数据 MPU6050_Read_Accel(accel_raw[0], accel_raw[1], accel_raw[2]); MPU6050_Read_Gyro(gyro_raw[0], gyro_raw[1], gyro_raw[2]); temperature MPU6050_Read_Temperature(); // 应用校准 MPU6050_Apply_Calibration(accel_raw, sensor_calib.accel_offset); MPU6050_Apply_Calibration(gyro_raw, sensor_calib.gyro_offset); // 应用滤波 MPU6050_Apply_Filter(sensor_filter, accel_raw); MPU6050_Apply_Filter(sensor_filter, gyro_raw); // 姿态解算100ms周期 MPU6050_Complementary_Filter(current_attitude, accel_raw, gyro_raw, 0.1f); // 通过串口输出数据用于调试 printf(Pitch: %.2f, Roll: %.2f, Yaw: %.2f, Temp: %.2fC\r\n, current_attitude.pitch, current_attitude.roll, current_attitude.yaw, temperature); DL_DelayMS(100); // 100ms采样周期 } }9.2 串口调试输出配置为了便于调试和验证传感器数据需要配置MSPM03507的串口功能// 串口初始化 void UART_Init(void) { // 启用UART外设时钟 DL_SYSCTL_enableSYSCTLPeripheral(SYSCTL_PERIPH_CLK_UART0); // 配置UART引脚 DL_GPIO_setMSPM0GPortPinFunction(GPIO_PA0_UART0_TX); DL_GPIO_setMSPM0GPortPinFunction(GPIO_PA1_UART0_RX); // UART配置115200波特率8数据位无校验1停止位 DL_UART_setBaudRate(UART0_INST, 115200); DL_UART_setDataLength(UART0_INST, UART_DATA_LEN_8); DL_UART_setParityNone(UART0_INST); DL_UART_setStopBits(UART0_INST, UART_STOP_BITS_1); // 启用UART DL_UART_enable(UART0_INST); } // 重定向printf到UART int _write(int file, char *ptr, int len) { for(int i 0; i len; i) { DL_UART_transmitDataBlocking(UART0_INST, ptr[i]); } return len; }10. 性能优化与功耗管理在实际应用中需要根据具体需求优化系统性能和功耗。10.1 低功耗模式配置MSPM03507支持多种低功耗模式可以根据应用需求进行配置// 进入低功耗模式 void Enter_Low_Power_Mode(void) { // 配置MPU6050进入低功耗模式 MPU6050_Write_Byte(MPU6050_PWR_MGMT_1, 0x40); // 睡眠模式 // 配置MSPM03507进入LPM3模式 DL_PCM_setPowerMode(PCM_LPM3_MODE); __WFI(); // 等待中断 } // 唤醒处理 void Wake_From_Low_Power(void) { // 唤醒MPU6050 MPU6050_Write_Byte(MPU6050_PWR_MGMT_1, 0x00); DL_DelayMS(100); // 重新校准传感器可选 MPU6050_Auto_Calibrate(sensor_calib); }10.2 采样率优化根据应用需求调整采样率平衡数据精度和系统负载// 配置MPU6050采样率 void MPU6050_Set_Sample_Rate(uint8_t rate) { // 采样率 陀螺仪输出率 / (1 SMPLRT_DIV) // 陀螺仪输出率通常为1kHz或8kHz MPU6050_Write_Byte(MPU6050_SMPLRT_DIV, rate); } // 根据应用场景动态调整采样率 void Adaptive_Sample_Rate_Control(void) { static uint32_t motion_counter 0; int16_t gyro_raw[3]; MPU6050_Read_Gyro(gyro_raw, gyro_raw1, gyro_raw2); // 检测运动强度 uint32_t motion_intensity abs(gyro_raw[0]) abs(gyro_raw[1]) abs(gyro_raw[2]); if(motion_intensity 1000) // 高强度运动 { MPU6050_Set_Sample_Rate(0); // 最高采样率 motion_counter 0; } else if(motion_intensity 100) // 中等强度运动 { MPU6050_Set_Sample_Rate(9); // 100Hz采样率 motion_counter 0; } else // 静止或微动 { motion_counter; if(motion_counter 50) // 持续静止5秒 { MPU6050_Set_Sample_Rate(99); // 10Hz采样率以节省功耗 } } }11. 常见问题与解决方案在实际开发过程中可能会遇到各种问题以下是常见问题的排查方法。11.1 I2C通信问题问题现象可能原因解决方案读取设备ID失败硬件连接错误检查VCC、GND、SDA、SCL连接I2C无响应上拉电阻缺失在SDA和SCL线上添加4.7kΩ上拉电阻数据读取错误时序问题调整I2C时钟频率检查延时设置偶尔通信失败电源噪声增加电源去耦电容缩短连接线11.2 传感器数据异常问题现象可能原因解决方案加速度数据漂移未进行校准执行自动校准程序姿态角计算不稳定滤波器参数不当调整互补滤波系数或使用DMP温度读数异常传感器过热检查工作环境温度确保在-40°C到85°C范围内陀螺仪零点偏移传感器安装不平确保传感器水平安装重新校准11.3 性能优化问题问题现象可能原因解决方案功耗过高采样率设置不当根据运动状态动态调整采样率响应延迟滤波器过度平滑减少滤波窗口大小或使用自适应滤波数据丢失FIFO溢出增加数据读取频率或使用DMP的FIFO功能计算精度不足数据类型选择不当使用浮点数计算或定点数优化12. 实际应用案例MPU6050与MSPM03507的组合可以应用于多种实际场景以下是几个典型应用案例。12.1 无人机飞控系统在四旋翼无人机中MPU6050用于检测飞行姿态MSPM03507作为飞控主处理器// 无人机姿态控制示例 void Drone_Attitude_Control(void) { MPU6050_Attitude_t current_attitude; int16_t motor_speed[4]; // 读取当前姿态 MPU6050_Complementary_Filter(current_attitude, accel_data, gyro_data, 0.01f); // PID控制器计算电机速度 motor_speed[0] Base_Speed PID_Pitch(current_attitude.pitch) PID_Roll(current_attitude.roll); motor_speed[1] Base_Speed - PID_Pitch(current_attitude.pitch) PID_Roll(current_attitude.roll); motor_speed[2] Base_Speed - PID_Pitch(current_attitude.pitch) - PID_Roll(current_attitude.roll); motor_speed[3] Base_Speed PID_Pitch(current_attitude.pitch) - PID_Roll(current_attitude.roll); // 限制电机速度在安全范围内 for(int i 0; i 4; i) { motor_speed[i] constrain(motor_speed[i], MIN_SPEED, MAX_SPEED); } // 更新电机PWM输出 Update_Motor_PWM(motor_speed); }12.2 运动追踪设备用于可穿戴设备中的运动检测和活动识别// 运动状态识别 typedef enum { STATE_STATIONARY, STATE_WALKING, STATE_RUNNING, STATE_UNKNOWN } Motion_State_t; Motion_State_t Recognize_Motion_State(const int16_t* accel, const int16_t* gyro) { static uint32_t step_count 0; static float energy 0; // 计算运动能量 float current_energy sqrtf(accel[0]*accel[0] accel[1]*accel[1] accel[2]*accel[2]) - 1.0f; energy 0.9f * energy 0.1f * fabsf(current_energy); // 步数检测基于加速度峰值 if(current_energy 0.3f energy 0.2f) { step_count; } // 根据能量水平分类运动状态 if(energy 0.05f) return STATE_STATIONARY; else if(energy 0.3f) return STATE_WALKING; else if(energy 0.3f) return STATE_RUNNING; else return STATE_UNKNOWN; }12.3 物联网传感节点在物联网应用中MPU6050用于检测设备状态变化MSPM03507处理数据并通过无线模块上传// 物联网传感数据上传 void IoT_Sensor_Upload(void) { MPU6050_Attitude_t attitude; float temperature; char json_buffer[256]; // 读取传感器数据 MPU6050_Complementary_Filter(attitude, accel_data, gyro_data, 1.0f); temperature MPU6050_Read_Temperature(); // 构建JSON数据包 snprintf(json_buffer, sizeof(json_buffer), {\pitch\:%.2f,\roll\:%.2f,\yaw\:%.2f,\temp\: