STM32H743+BMI088 I2C调试记录

最近遇到需要调试博世的一款IMU芯片,调好了留个纪念~

首先CUBEMX配置I2C,这里不多做赘述,参数默认即可。

然后要关注一下硬件IMU来判断一下I2C地址:

根据数据手册可以得知加速度计和陀螺仪的地址是不一样的,根据硬件接法的不同有两种情况,此处大家根据硬件选择。

这个芯片我们需要的数据就是三个方向的加速度和角加速度,我们首先来看加速度:

他这个加速度是一个s16的值,由两个u8拼凑而成,同时还有一个寄存器用来控制加速度的范围:

所以我们要做的就是读寄存器,然后拼接值,再根据范围确定这个值,同时这个加速度值还有一个计算方式:

这边不多做赘述,我们直接上代码:

//开始之前首先要对芯片进行复位操作
void imu_init(void) {
    i2c_txbuf[0] = 0x7E;
    i2c_txbuf[1] = 0xB6;
    HAL_I2C_Master_Transmit(&hi2c1, 0x30, i2c_txbuf, 2, 1000);
    HAL_Delay(10);
    i2c_txbuf[0] = 0x7D;
    i2c_txbuf[1] = 0x04;
    HAL_I2C_Master_Transmit(&hi2c1, 0x30, i2c_txbuf, 2, 1000);
    HAL_Delay(10);
    i2c_txbuf[0] = 0x12;
}

float calculateAccel(int16_t Accel_int16) {
    float Accel_in_mg = (Accel_int16 / 32768.0) * 1000 * pow(2, (bmi088.acc_range + 1)) * 1.5;
    return Accel_in_mg;
}

void set_acc_range(uint8_t pRange) {
    i2c_txbuf[0] = 0x41;
    i2c_txbuf[1] = pRange;
    HAL_I2C_Master_Transmit(&hi2c1, 0x30, i2c_txbuf, 2, 1000);
}

void get_acc_range(void) {
    i2c_txbuf[0] = 0x41;
    HAL_I2C_Master_Transmit(&hi2c1, 0x30, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0x30, i2c_rxbuf, 1, 1000);
    bmi088.acc_range = i2c_rxbuf[0];
}

void set_acc_bwp_odr(uint8_t pBwp, uint8_t pOdr) {
    i2c_txbuf[0] = 0x40;
    i2c_txbuf[1] = ((pBwp << 4) | (pOdr & 0x0F));
    HAL_I2C_Master_Transmit(&hi2c1, 0x30, i2c_txbuf, 2, 1000);
}

void get_acc_bwp_odr(void) {
    i2c_txbuf[0] = 0x40;
    HAL_I2C_Master_Transmit(&hi2c1, 0x30, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0x30, i2c_rxbuf, 1, 1000);
    bmi088.acc_bwp = (i2c_rxbuf[0] >> 4);
    bmi088.acc_odr = (i2c_rxbuf[0] & 0x0F);
}

void get_accelerometer(void) {
    uint8_t acc_l = 0;
    uint8_t acc_m = 0;
    //ACC_X
    i2c_txbuf[0] = 0x12;
    HAL_I2C_Master_Transmit(&hi2c1, 0x30, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0x30, i2c_rxbuf, 1, 1000);
    acc_l = i2c_rxbuf[0];
    i2c_txbuf[0] = 0x13;
    HAL_I2C_Master_Transmit(&hi2c1, 0x30, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0x30, i2c_rxbuf, 1, 1000);
    acc_m = i2c_rxbuf[0];
    bmi088.acceleration_x = calculateAccel(((int16_t)(acc_m << 8) | acc_l));
    //ACC_Y
    i2c_txbuf[0] = 0x14;
    HAL_I2C_Master_Transmit(&hi2c1, 0x30, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0x30, i2c_rxbuf, 1, 1000);
    acc_l = i2c_rxbuf[0];
    i2c_txbuf[0] = 0x15;
    HAL_I2C_Master_Transmit(&hi2c1, 0x30, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0x30, i2c_rxbuf, 1, 1000);
    acc_m = i2c_rxbuf[0];
    bmi088.acceleration_y = calculateAccel(((int16_t)(acc_m << 8) | acc_l));
    //ACC_Z
    i2c_txbuf[0] = 0x16;
    HAL_I2C_Master_Transmit(&hi2c1, 0x30, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0x30, i2c_rxbuf, 1, 1000);
    acc_l = i2c_rxbuf[0];
    i2c_txbuf[0] = 0x17;
    HAL_I2C_Master_Transmit(&hi2c1, 0x30, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0x30, i2c_rxbuf, 1, 1000);
    acc_m = i2c_rxbuf[0];
    bmi088.acceleration_z = calculateAccel(((int16_t)(acc_m << 8) | acc_l));
}

之后是角加速度,与加速度同样:

思路上还是一样:

void set_gyro_range(uint8_t pRange) {
    i2c_txbuf[0] = 0x0F;
    i2c_txbuf[1] = pRange;
    HAL_I2C_Master_Transmit(&hi2c1, 0xD0, i2c_txbuf, 2, 1000);
}

void get_gyro_range(void) {
    i2c_txbuf[0] = 0x0F;
    HAL_I2C_Master_Transmit(&hi2c1, 0xD0, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0xD0, i2c_rxbuf, 1, 1000);
    bmi088.gyro_range = i2c_rxbuf[0];
}

void set_gyro_bwp(uint8_t pBwp) {
    i2c_txbuf[0] = 0x10;
    i2c_txbuf[1] = pBwp;
    HAL_I2C_Master_Transmit(&hi2c1, 0xD0, i2c_txbuf, 2, 1000);
}

void get_gyro_bwp(void) {
    i2c_txbuf[0] = 0x10;
    HAL_I2C_Master_Transmit(&hi2c1, 0xD0, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0xD0, i2c_rxbuf, 1, 1000);
    bmi088.gyro_bwp = i2c_rxbuf[0];
}

void get_gyro(void) {
    uint8_t acc_l = 0;
    uint8_t acc_m = 0;
    //ACC_X
    i2c_txbuf[0] = 0x02;
    HAL_I2C_Master_Transmit(&hi2c1, 0xD0, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0xD0, i2c_rxbuf, 1, 1000);
    acc_l = i2c_rxbuf[0];
    i2c_txbuf[0] = 0x03;
    HAL_I2C_Master_Transmit(&hi2c1, 0xD0, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0xD0, i2c_rxbuf, 1, 1000);
    acc_m = i2c_rxbuf[0];
    bmi088.gyro_x = ((int16_t)(acc_m << 8) | acc_l);
    //ACC_Y
    i2c_txbuf[0] = 0x04;
    HAL_I2C_Master_Transmit(&hi2c1, 0xD0, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0xD0, i2c_rxbuf, 1, 1000);
    acc_l = i2c_rxbuf[0];
    i2c_txbuf[0] = 0x05;
    HAL_I2C_Master_Transmit(&hi2c1, 0xD0, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0xD0, i2c_rxbuf, 1, 1000);
    acc_m = i2c_rxbuf[0];
    bmi088.gyro_y = ((int16_t)(acc_m << 8) | acc_l);
    //ACC_Z
    i2c_txbuf[0] = 0x06;
    HAL_I2C_Master_Transmit(&hi2c1, 0xD0, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0xD0, i2c_rxbuf, 1, 1000);
    acc_l = i2c_rxbuf[0];
    i2c_txbuf[0] = 0x07;
    HAL_I2C_Master_Transmit(&hi2c1, 0xD0, i2c_txbuf, 1, 1000);
    HAL_I2C_Master_Receive(&hi2c1, 0xD0, i2c_rxbuf, 1, 1000);
    acc_m = i2c_rxbuf[0];
    bmi088.gyro_z = ((int16_t)(acc_m << 8) | acc_l);
}

本身并不是特别复杂,主要是啃芯片手册花了些时间,希望能够对你有所帮助~

  • 16
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值