wheel_legged_gimbal/modules/BMI088/bmi088.md

3.0 KiB

BMI088

示例

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. 写入的数据