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

共2条 1/1 1 跳转至

【STEVAL-STWINKT1B】:结合STMcubeMX读取IIS2DH数据

高工
2026-04-01 19:55:33     打赏

一:IIS2DH芯片描述

  IIS2DH是一款超低功耗高性能三轴线性加速度计,具有数字I2C/SPI串行接口标准输出。

  IIS2DH具有用户可选的满量程:+2g/+4g/+8g/+16g,能够以1Hz至5.3kHz的输出数据速率测量加速度。

  该设备可配置为通过两个独立的惯性唤醒自由落体事件以及设备自身的位置来生成中断信号。

  自检功能允许用户在最终应用中检查传感器的功能。

  IIS2DH采用小型薄型塑料焊盘网格阵列封装(LGA),并保证可在-40°C至+85°C的宽温度范围内工作。

二:特征:

  3个磁场通道

  最高可达+50高斯磁动态范围

  16位数据输出.

  SPI/12C串行接口

  模拟供电电压1.71V至3.6V

  可选电源模式/分辨率

  单测量模式最高可达150赫兹

  支持硬铁补偿

  可编程中断发生器嵌入式自检功能

  嵌入式温度传感器

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

三:原理图

07-1 IIS2DH原理图.png

stm32 cube MX软件配置:

07-2 IIS2DH cube MX配置.png

SPI 配置参数;

通信模式:SPI模式3(CPOL=1, CPHA=1):时钟空闲时为高电平,数据在上升沿被采集

CS引脚:低电平有效,在整个传输过程中保持低电平

数据位序:最高有效位(MSB)在前

4线制引脚:CS(片选)、SPC(时钟)、SDI(数据输入)、SDO(数据输出)

读取IIS2DH加速度计的数据,无论是通过I²C还是SPI接口,核心流程都是标准的:先初始化传感器,然后连续读取其输出寄存器。不过该开发板使用SPI的通讯方式进行硬件连接。

软件编写步骤如下所示:

初始化传感器

在读取数据之前,需要对IIS2DH进行配置,以确定其工作模式。关键步骤如下:

接口选择:通过CS引脚的电平选择通信接口。CS接高电平(Vdd_IO)为I²C模式;CS接低电平(GND)则为SPI模式。

设置量程和输出数据率:通过配置CTRL_REG1和CTRL_REG4等寄存器,设置加速度计的量程(如±2g, ±4g, ±8g, ±16g)和输出数据率(ODR,从1Hz到5kHz)。

使能轴:在CTRL_REG1寄存器中,需要使能X、Y、Z轴的输出。

读取加速度数据

初始化完成后,就可以循环读取三个轴的加速度值了。在读取数据时,有两种方式可选:

单次读取:分别读取X、Y、Z轴的高低两个寄存器(每个轴占16位,即2个字节)。

块/连续读取:从寄存器OUT_X_L(地址0x28)开始,一次性连续读取6个字节(X、Y、Z各占2个字节)

读取地址的特别说明(非常重要) 在发起多字节读取命令时,需要设置寄存器地址的最高位(bit 7)为1,以启用地址自动递增功能。例如,要读取X轴的低位寄存器(地址0x28),实际发送的读取地址应为0x28 | 0x80 = 0xA8

数据转换

从寄存器读取到的原始数据是两个8位字节(一个16位的原始值),需要进行转换才能得到以重力加速度 g 为单位的物理量。 转换公式为:加速度 = 原始值 / 灵敏度

四:代码如下所示:

SPI 读取函数实现

1:单字节的读取

/**
 * @brief 通过SPI读取IIS2DH单个寄存器
 * @param spi_handle  SPI句柄
 * @param reg_addr    寄存器地址(7位,最高位为0)
 * @param data        读取的数据(输出)
 * @return 0=成功,其他=失败
 */
int IIS2DH_SPI_ReadByte(SPI_HandleTypeDef *spi_handle, uint8_t reg_addr, uint8_t *data)
{
    uint8_t tx_buf[2];
    uint8_t rx_buf[2];
    
    // 构建命令:寄存器地址 + 读标志(bit7=1)
    tx_buf[0] = reg_addr | 0x80;  // 设置读标志位
    tx_buf[1] = 0xFF;              // 占位字节,用于读取数据
    
    // CS引脚拉低(根据实际硬件实现)
    HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
    
    // 发送命令并接收数据
    HAL_SPI_TransmitReceive(spi_handle, tx_buf, rx_buf, 2, HAL_MAX_DELAY);
    
    // CS引脚拉高
    HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
    
    *data = rx_buf[1];  // 第二个字节是读取的数据
    return 0;
}
2:多字节的连续读取函数

/**
 * @brief 通过SPI连续读取IIS2DH多个寄存器
 * @param spi_handle  SPI句柄
 * @param reg_addr    起始寄存器地址
 * @param data        数据缓冲区
 * @param len         要读取的字节数
 * @return 0=成功,其他=失败
 */
int IIS2DH_SPI_ReadMultiBytes(SPI_HandleTypeDef *spi_handle, uint8_t reg_addr, 
                               uint8_t *data, uint8_t len)
{
    uint8_t tx_buf[1];
    uint8_t rx_buf[1];
    
    if (len == 0) return -1;
    
    // 构建命令:寄存器地址 + 读标志(bit7=1)+ 地址递增(bit6=1)
    // 注意:命令字节中bit1(MS位)需要置1以实现地址自动递增
    // 命令格式:bit0=RW, bit1=MS, bit2-7=AD
    // 简化写法:直接使用(reg_addr << 1) | 0x03
    uint8_t cmd = (reg_addr << 1) | 0x03;  // RW=1, MS=1
    // 或者更直观的写法:
    // uint8_t cmd = (reg_addr << 1) | (1 << 0) | (1 << 1);
    
    // CS引脚拉低
    HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
    
    // 发送命令字节
    HAL_SPI_Transmit(spi_handle, &cmd, 1, HAL_MAX_DELAY);
    
    // 连续读取len个字节的数据
    for (int i = 0; i < len; i++) {
        tx_buf[0] = 0xFF;  // 发送占位字节
        HAL_SPI_TransmitReceive(spi_handle, tx_buf, rx_buf, 1, HAL_MAX_DELAY);
        data[i] = rx_buf[0];
    }
    
    // CS引脚拉高
    HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
    
    return 0;
}
3:读取加速度数据示例

/**
 * @brief 读取IIS2DH三轴加速度数据
 * @param spi_handle  SPI句柄
 * @param accel       加速度数据结构体(输出)
 * @param sensitivity 灵敏度(根据量程设置,如±2g时为16384)
 */
void IIS2DH_ReadAcceleration(SPI_HandleTypeDef *spi_handle, 
                              int16_t *accel_x, int16_t *accel_y, int16_t *accel_z,
                              uint16_t sensitivity)
{
    uint8_t raw_data[6];
    
    // 从OUT_X_L(0x28)开始连续读取6个字节
    IIS2DH_SPI_ReadMultiBytes(spi_handle, 0x28, raw_data, 6);
    
    // 合并高低字节(低字节在前,高字节在后)
    *accel_x = (int16_t)((uint16_t)raw_data[1] << 8 | raw_data[0]);
    *accel_y = (int16_t)((uint16_t)raw_data[3] << 8 | raw_data[2]);
    *accel_z = (int16_t)((uint16_t)raw_data[5] << 8 | raw_data[4]);
    
    // 可选:转换为以g为单位的物理值
    // float x_g = (float)*accel_x / sensitivity;
    // float y_g = (float)*accel_y / sensitivity;
    // float z_g = (float)*accel_z / sensitivity;
}
五:实物测试如下:

07-2 IIS2DH 测试图片.png

芯片使用注意事项:

  CS引脚控制:每次SPI传输前拉低CS,传输完成后拉高CS

  地址递增:多字节读取时,必须设置命令字节的MS位(bit1)为1

  数据对齐:加速度数据为16位,低字节在前(Little Endian)

  通信速度:SPI时钟频率不超过10MHz(参考数据手册)

  多字节读取限制:地址递增仅在当前页内有效,不要跨越寄存器地址边界。




关键词: STEVAL-STWINKT1B     IIS2DH    

院士
2026-04-04 22:44:30     打赏
2楼

像加速度计这种传感器的采样率要达到多高才可以稳定住无人机的机身啊?!


共2条 1/1 1 跳转至

回复

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