HPM5361EVK开发板与MPU9250传感器SPI通信实战

发布时间:2026/7/17 20:48:58
HPM5361EVK开发板与MPU9250传感器SPI通信实战 1. HPM5361EVK开发板与MPU9250传感器概述HPM5361EVK是先楫半导体推出的一款高性能微控制器开发板基于RISC-V架构设计主打高实时性和低功耗特性。这块开发板在运动控制和传感器数据处理方面表现尤为突出这也是为什么选择它来驱动MPU9250这款九轴运动传感器的原因。MPU9250是InvenSense公司推出的经典运动传感器集成了三轴陀螺仪、三轴加速度计和三轴磁力计。它支持I2C和SPI两种通信协议最高SPI时钟频率可达20MHz。在实际项目中SPI接口因其全双工、高带宽的特性特别适合需要高频数据采集的运动追踪场景。开发板上SPI1接口的物理引脚分布如下SPI1_CSNJ3插座第24脚SPI1_SCLKJ3插座第23脚SPI1_MISOJ3插座第21脚SPI1_MOSIJ3插座第19脚注意HPM5361的SPI控制器支持主从模式切换但在传感器应用中通常配置为主模式。开发板默认的SPI时钟分频系数可能较高需要根据MPU9250的规格调整。2. 硬件连接与SPI物理层配置2.1 线缆连接规范使用杜邦线连接时建议采用不同颜色区分信号线红色3.3V电源MPU9250的VCC黑色GND接开发板J3的任一GND引脚黄色SCLKJ3-23蓝色MOSIJ3-19绿色MISOJ3-21白色CSNJ3-24MPU9250的AD0引脚需要接地选择SPI模式INT引脚可悬空或接GPIO用于中断触发。实际接线时线长最好控制在15cm以内过长的导线可能引入信号完整性问题。2.2 SPI参数计算MPU9250的SPI时序要求模式0CPOL0, CPHA0最大SCLK频率20MHz数据位宽8bitHPM5361的系统时钟通常为200MHzSPI时钟分频计算公式SPI_SCLK SYSTEM_CLK / (2 * (DIVIDER 1))要得到10MHz时钟保留余量DIVIDER应设为200 / (2*10) - 1 9实测发现当分频值设为4对应20MHz时某些批次MPU9250会出现数据错位建议初始设置为910MHz。3. SDK驱动层实现详解3.1 SPI控制器初始化使用HPM SDK的hpm_spi驱动库关键配置步骤如下// SPI初始化结构体 spi_control_config_t control_cfg { .csn_pin BOARD_APP_SPI_CS_PIN, .csn_level SPI_CSN_ACTIVE_LOW, .clk_speed_hz 10 * 1000 * 1000, .common_config { .mode spi_master_mode, .dummy_data 0xFF, .data_len_in_bits 8, .sclk_mode spi_sclk_mode_0, } }; // 引脚复用配置 init_spi_pins(BOARD_APP_SPI_BASE); // 控制器初始化 spi_init(BOARD_APP_SPI_BASE, control_cfg);3.2 MPU9250寄存器读写协议MPU9250的SPI通信规则写操作最高位为0读操作最高位为1寄存器地址为7位读加速度计数据的示例代码uint8_t read_mpu9250_reg(uint8_t reg) { uint8_t cmd reg | 0x80; // 设置读标志 uint8_t recv_data 0; spi_write_data(BOARD_APP_SPI_BASE, cmd, 1); spi_read_data(BOARD_APP_SPI_BASE, recv_data, 1); return recv_data; } void write_mpu9250_reg(uint8_t reg, uint8_t val) { uint8_t cmd[2] {reg 0x7F, val}; // 清除读标志 spi_write_data(BOARD_APP_SPI_BASE, cmd, sizeof(cmd)); }4. 传感器数据采集与处理4.1 初始化序列MPU9250上电后需要执行以下初始化步骤复位设备PWR_MGMT_1寄存器写0x80等待50ms复位完成选择时钟源PWR_MGMT_1写0x01配置加速度计量程±4g对应AFS_SEL1配置陀螺仪量程±500dps对应FS_SEL1启用磁力计INT_PIN_CFG写0x02关键细节磁力计需要额外通过I2C主接口访问在SPI模式下需启用旁路模式INT_PIN_CFG[1]1。4.2 数据读取优化高效读取9轴数据的推荐方法#pragma pack(push, 1) typedef struct { int16_t accel_x; int16_t accel_y; int16_t accel_z; int16_t temp; int16_t gyro_x; int16_t gyro_y; int16_t gyro_z; uint8_t mag_st1; int16_t mag_x; int16_t mag_y; int16_t mag_z; uint8_t mag_st2; } mpu9250_raw_data_t; #pragma pack(pop) void read_mpu9250_all(mpu9250_raw_data_t *data) { uint8_t cmd[15] {0x80 | 0x3B}; // 从ACCEL_XOUT_H开始读 spi_csn_active(BOARD_APP_SPI_CS_PIN); spi_write_data_then_read_data(BOARD_APP_SPI_BASE, cmd, 1, (uint8_t*)data, 14); spi_csn_inactive(BOARD_APP_SPI_CS_PIN); // 单独读取磁力计数据 cmd[0] 0x80 | 0x02; // MAG_ST1地址 spi_csn_active(BOARD_APP_SPI_CS_PIN); spi_write_data_then_read_data(BOARD_APP_SPI_BASE, cmd, 1, data-mag_st1, 8); spi_csn_inactive(BOARD_APP_SPI_CS_PIN); }4.3 数据转换公式原始数据转换为物理量加速度计±4g量程accel_g raw_value / 8192.0f陀螺仪±500dps量程gyro_dps raw_value / 65.5f温度传感器temp_c raw_value / 333.87f 21.0f磁力计±4800μT量程mag_ut raw_value * 0.6f5. 调试技巧与性能优化5.1 常见问题排查现象1读取数据全为0xFF或0x00检查CSN引脚电平是否正常确认SPI模式设置为Mode0测量SCLK信号是否正常示波器观察现象2磁力计数据不更新检查INT_PIN_CFG寄存器的旁路模式是否启用读取MAG_ST1寄存器确认数据就绪位两次读取间隔需大于10ms磁力仪转换时间5.2 DMA传输配置对于高频采样场景建议启用DMA传输dma_config_t dma_cfg { .src BOARD_APP_SPI_BASE, .dst (uint32_t)data_buf, .size sizeof(data_buf), .burst_len 4, .src_width DMA_TRANSFER_WIDTH_BYTE, .dst_width DMA_TRANSFER_WIDTH_BYTE }; hpm_dma_setup_channel(BOARD_APP_DMA, DMA_CH_SPI_RX, dma_cfg); spi_enable_dma(BOARD_APP_SPI_BASE, SPI_DMA_RX);5.3 实时性优化技巧将SPI时钟提升到15MHz需确保信号质量使用RTOS时将SPI操作放在高优先级任务预读取下一组寄存器地址减少CSN切换延迟对原始数据应用滑动平均滤波窗口大小4-8