sentry_chassis_hzz/modules/BMI088/bmi088.md

99 lines
3.0 KiB
Markdown

# BMI088
## 示例
```c
BMI088_Init_Config_s imu_config = {
.spi_acc_config={
.GPIOx=GPIOA,
.GPIOx=GPIO_PIN_4,
.spi_handle=&hspi1,
},
.spi_gyro_config={
.GPIOx=GPIOB,
.GPIOx=GPIO_PIN_0,
.spi_handle=&hspi1,
},
.acc_int_config={
.exti_mode=EXTI_TRIGGER_FALLING,
.GPIO_Pin=GPIO_PIN_4,
.GPIOx=GPIOC,
},
.gyro_int_config={
.exti_mode=EXTI_TRIGGER_FALLING,
.GPIO_Pin=GPIO_PIN_5,
.GPIOx=GPIOC,
},
.heat_pid_config={
.Kp=0.0f,
.Kd=0.0f,
.Ki=0.0f,
.MaxOut=0.0f,
.DeadBand=0.0f,
},
.heat_pwm_config={
.channel=TIM_CHANNEL_1,
.htim=&htim1,
},
.cali_mode=BMI088_CALIBRATE_ONLINE_MODE,
.work_mode=BMI088_BLOCK_PERIODIC_MODE,
};
BMI088Instance* imu=BMI088Register(&imu_config);
```
## IT非阻塞模式下BMI088读取流程
数据准备完成标志位:`uint8_t BMI088_READY_FLAG` 总共8个位 也可以用位域可读性更高
1. 当accel int中断发生,开启DMA SPI传输,完成后将acc ready置位
2. 当gyro int中断发生,开启DMA SPI传输,完成后将gyro ready置位
3. 当温度数据中断(温度传感器在accel内部,也是accel int)发生,开启DMA传输,完成后将温度标志位置位
> 由于DMA传输非阻塞,启动传输后只有到传输完成时才会拉高片选结束SPI transfer,因此需要在callback中加入标志位置位的操作.
这可以通过条件编译完成.
温度数据不需要和accel和gyro同步,它不参与姿态解算,可以不用管.
当加速度数据和陀螺仪数据都准备完成之后,唤醒姿态解算任务INs_taSk,进行一次解算.唤醒可以通过软件开启EXTI中断,在中断中调用实时系统的vTaskNotifyFromISR()完成,也可以将任务ready标志位置位,当运行到对应位置时检查标志位判断是否要进行任务.时间间隔不是大问题,inS_TAsK中有dwt用于计算两次任务执行的间隔,它将会自动处理好bias的大小
`__HAL_GPIO_EXTI_GENERATE_SWIT()` `HAL_EXTI_GENERATE_SWI()` 可以触发软件中断
of course,两者的数据更新实际上可以异步进行,这里为了方便起见当两者数据都准备好以后再行融合
## 数据读写规则(so called 16-bit protocol)
加速度计读取read:
1. bit 0 :1 bit 1-7: reg address
2. dummy read,加速度计此时返回的数据无效
3. 真正的数据从第三个字节开始.
通过SPI传输三个字节(分三次)
byte1: 1(读)+7位寄存器地址
byte2: 没用
byte3: 读取到的数据
write写入:
1. bit 0: 0 bit1-7: reg address
2. 要写入寄存器的数据(注意没有dummy byte)
---
**注意,陀螺仪和加速度计的读取不同**
陀螺仪gyro读取read:
1. bit 0 :1 bit1-7: reg address
2. 读回的数据
通过SPI传输两个字节(分两次)
byte1: 1(读)+7位寄存器地址
byte2: 读取到的数据
write写入:
1. bit0 : 0 bit1-7 : reg address
2. 写入的数据