最近遇到需要调试博世的一款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);
}
本身并不是特别复杂,主要是啃芯片手册花了些时间,希望能够对你有所帮助~