这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【STEVAL-STWINKT1B】:读取ISM330DHCX数据

共1条 1/1 1 跳转至

【STEVAL-STWINKT1B】:读取ISM330DHCX数据

高工
2026-04-20 13:33:02     打赏

一:ISM330DHCX知识分享:

  带可选满量程的3D加速度计:+2/+4/+8/+16g

  带扩展可选满量程的3D陀螺仪:+125/±250/±500/±1000/±2000/±4000 dps

  扩展温度范围从-40到+105°C嵌入式补偿,确保温度变化下的高稳定性

  SPI/I2C串行接口

  辅助SPI串行接口,用于陀螺仪和加速度计的数据输出(OIS及其他稳定应用)

  六通道同步输出

  传感器集线器功能,可高效从额外外部传感器收集数据;

  嵌入式智能FIFO,最大支持9千字节

  可编程有限状态机,用于处理加速度计、陀螺仪和外部传感器的数据

  机器学习核心智能嵌入式功能与中断:倾斜检测、自由落体、唤醒、6D/4D方向、单击与双击

  嵌入式计步器、步数检测器和计数器,用于医疗保健应用

  模拟供电电压:1.71V至3.6V

  嵌入式温度传感器陀螺仪和加速度计均内置自检功能高抗冲击性

  符合ECOPACK、RoHS和“绿色”标准

二:STM32cube MX配置

2.1 安装 X-CUBE-MEMS1 扩展包

  1.打开 STM32CubeMX

  2.进入 "Software Packs" 选项卡

  3.点击 "Select Components" 或 "Manage Software Packs"

  4.搜索 "X-CUBE-MEMS1"

  5.点击安装最新版本(如 v6.2.0 或更高版本)

2.2 芯片的原理图:

09-2 IIS330DHCX 原理图.png

2.3 添加传感器组件

  1.在 "Pinout & Configuration" 视图的左侧,找到 "Software Packs" 部分

  2.展开 "X-CUBE-MEMS1"

  3.找到并勾选 "Sensor" 组件

  4.点击确认添加

2.4 配置 ISM330DHCX 传感器

  在添加传感器组件后,会出现配置界面:

  1.在 "Middleware" 部分找到 "X-CUBE-MEMS1"

  2.点击进入配置页面

  3.在 "Sensor" 列表中,找到 "ISM330DHCX"

  4.配置参数:

09-1 stm32cube MX软件配置.png

三:软件代码:

3.1 SPI 通讯底层函数

// SPI写寄存器
static uint8_t ism330dhcx_spi_write(SPI_HandleTypeDef *hspi, uint16_t cs_pin, 
                                     uint8_t reg_addr, uint8_t *data, uint16_t len)
{
    uint8_t tx_buffer[256];
    uint8_t rx_buffer[256];
    uint8_t ret = 0;
    
    // CS片选拉低
    HAL_GPIO_WritePin(CS_GPIO_Port, cs_pin, GPIO_PIN_RESET);
    
    // 发送寄存器地址(写操作,bit7=0)
    tx_buffer[0] = reg_addr & 0x7F;
    for(uint16_t i = 0; i < len; i++) {
        tx_buffer[i+1] = data[i];
    }
    
    // SPI收发数据
    HAL_SPI_TransmitReceive(hspi, tx_buffer, rx_buffer, len+1, HAL_MAX_DELAY);
    
    // CS片选拉高
    HAL_GPIO_WritePin(CS_GPIO_Port, cs_pin, GPIO_PIN_SET);
    
    return ret;
}

// SPI读寄存器
static uint8_t ism330dhcx_spi_read(SPI_HandleTypeDef *hspi, uint16_t cs_pin,
                                    uint8_t reg_addr, uint8_t *data, uint16_t len)
{
    uint8_t tx_buffer[256];
    uint8_t rx_buffer[256];
    
    // CS片选拉低
    HAL_GPIO_WritePin(CS_GPIO_Port, cs_pin, GPIO_PIN_RESET);
    
    // 发送寄存器地址(读操作,bit7=1)
    tx_buffer[0] = reg_addr | 0x80;
    for(uint16_t i = 0; i < len; i++) {
        tx_buffer[i+1] = 0xFF;  // 发送dummy数据以产生时钟
    }
    
    // SPI收发数据
    HAL_SPI_TransmitReceive(hspi, tx_buffer, rx_buffer, len+1, HAL_MAX_DELAY);
    
    // 复制接收到的数据
    for(uint16_t i = 0; i < len; i++) {
        data[i] = rx_buffer[i+1];
    }
    
    // CS片选拉高
    HAL_GPIO_WritePin(CS_GPIO_Port, cs_pin, GPIO_PIN_SET);
    
    return 0;
}

数据处理函数:

/**
 * @brief 批量读取加速度计和陀螺仪数据(6轴同步)
 * @param hspi SPI句柄
 * @param cs_pin CS引脚
 * @param acc_data 加速度数据结构体(输出)
 * @param gyro_data 陀螺仪数据结构体(输出)
 * @return HAL状态
 */
HAL_StatusTypeDef ISM330DHCX_ReadAllAxes(SPI_HandleTypeDef *hspi, 
                                          uint16_t cs_pin,
                                          ISM330DHCX_Axes_t *acc_data,
                                          ISM330DHCX_Axes_t *gyro_data)
{
    uint8_t tx_buffer[15] = {0};
    uint8_t rx_buffer[15] = {0};
    int16_t raw_acc[3], raw_gyro[3];
    
    // CS片选拉低
    HAL_GPIO_WritePin(CS_GPIO_Port, cs_pin, GPIO_PIN_RESET);
    
    // 从OUTX_L_G开始连续读取14字节(陀螺仪+加速度计)
    // 读操作:最高位为1,自动地址递增
    tx_buffer[0] = ISM330DHCX_OUTX_L_G | 0x80 | 0x40;  // 0x80=读操作, 0x40=自动递增
    for(int i = 1; i < 15; i++) {
        tx_buffer[i] = 0xFF;  // 发送dummy数据产生时钟
    }
    
    // SPI收发
    HAL_SPI_TransmitReceive(hspi, tx_buffer, rx_buffer, 15, HAL_MAX_DELAY);
    
    // CS片选拉高
    HAL_GPIO_WritePin(CS_GPIO_Port, cs_pin, GPIO_PIN_SET);
    
    // 解析陀螺仪原始数据(小端格式)
    raw_gyro[0] = (int16_t)((rx_buffer[2] << 8) | rx_buffer[1]);  // OUTX_L_G, OUTX_H_G
    raw_gyro[1] = (int16_t)((rx_buffer[4] << 8) | rx_buffer[3]);  // OUTY_L_G, OUTY_H_G
    raw_gyro[2] = (int16_t)((rx_buffer[6] << 8) | rx_buffer[5]);  // OUTZ_L_G, OUTZ_H_G
    
    // 解析加速度计原始数据
    raw_acc[0] = (int16_t)((rx_buffer[8] << 8) | rx_buffer[7]);   // OUTX_L_A, OUTX_H_A
    raw_acc[1] = (int16_t)((rx_buffer[10] << 8) | rx_buffer[9]);  // OUTY_L_A, OUTY_H_A
    raw_acc[2] = (int16_t)((rx_buffer[12] << 8) | rx_buffer[11]); // OUTZ_L_A, OUTZ_H_A
    
    // 应用灵敏度转换为物理单位
    acc_data->x = (int32_t)((float)raw_acc[0] * acc_sensitivity);
    acc_data->y = (int32_t)((float)raw_acc[1] * acc_sensitivity);
    acc_data->z = (int32_t)((float)raw_acc[2] * acc_sensitivity);
    
    gyro_data->x = (int32_t)((float)raw_gyro[0] * gyro_sensitivity);
    gyro_data->y = (int32_t)((float)raw_gyro[1] * gyro_sensitivity);
    gyro_data->z = (int32_t)((float)raw_gyro[2] * gyro_sensitivity);
    
    return HAL_OK;
}

使用注意事项:

  数据格式:传感器输出16位有符号整数(int16_t),小端格式

  灵敏度计算:转换系数取决于量程设置,需在初始化时配置

  零偏校准:静止状态检测是实现零偏校准的前提

  滤波器选择:MCU资源受限时用互补滤波,资源充足可用卡尔曼滤波

四:串口数据如下所示:

09-3 IIS330DHCX 串口数据.png

五:调试过程中遇到问题:1:SPI 通信无响应

原因:

CS 引脚配置错误

SPI 时钟频率过高(超过 10MHz)

SA0 引脚未悬空(仍处于 I2C 模式)

解决方法:

使用示波器或逻辑分析仪检查 SPI 波形

降低 SPI 分频值,确保 SCLK < 10MHz

2:读取数据全为 0 或 0xFF

可能原因:

 SPI 读写函数中的命令格式错误

 片选时序不正确

解决方法:

确认读命令的最高位为 1(例如:reg | 0x80)

确认写命令的最高位为 0(例如:reg & 0x7F)

确保在每次 SPI 传输前后正确控制 CS 引脚。




关键词: STEVAL-STWINKT1B     ISM330DH    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]