SEASKY-BMI088技术手册

[!important|style:callout] 注意这是最早的V1.0 协议的产品,对现在的上位机并不适用。

1. 渲染

2. 实物

3. Seasky BMI088开源地址

BMI088_Master

4. 协议

5. BMI088模块16位寄存器

数据 说明
bit0 模块复位
bit1 陀螺仪校准
bit2 CAN输出使能
bit3 USART输出使能
bit4 保留
bit5 保留
bit6 保留
bit7 保留
bit8 保留
bit9 保留
bit10 保留
bit11 保留
bit12 保留
bit13 保留
bit14 USART命令有效控制位
bit15 CAN命令有效控制位
  • 上电复位状态bit2=1,bit3=1,其余位位0,即使能所有输出

  • 同时向模块发送CAN或USART数据,CAN数据具有更高优先级

  • 使用CAN发送数据 0X8004 ->关闭串口输出,CAN持续输出姿态数据

  • 使用USART发送数据 0X4008 ->在保证CAN未发送(bit15=0)的情况下,关闭CAN输出,USART持续输出,注意发送数据需要协议打包

6. UART方式通信协议

6.1. 通信要求

配置为波特率 1152008 位数据位,1 位停止位, 硬件流控, 校验位,发送频率 100Hz .

6.2. 接口协议说明

SEASKY通信协议-详情见 串口协议文件

  • BMI088端发送接口(float数据长度- 10)
数据 说明
IMU_USART_ID 0X0001
bmi088_flag 16位寄存器
float_data[0] accel.x
float_data[1] accel.y
float_data[2] accel.z
float_data[3] rate.x
float_data[4] rate.y
float_data[5] rate.z
float_data[6] gyro.yaw
float_data[7] gyro.yaw_c(连续)
float_data[8] gyro.pitch
float_data[9] gyro.roll
  • 发送函数(该模块发送调用函数)
void imu_usart_send(void)
{
    static uint8_t send_data[60];//保证大于发送的数据
    uint16_t tx_flag=0,send_data_len=0;

    /*发送寄存器赋值*/
    tx_flag |= imu_ctr_t.ctr.res&0x01;
    tx_flag |= (imu_ctr_t.ctr.cmd<<1)&0x01;

    /*发送的数据赋值*/
    imu_ctr_t.ctr.float_data[0] = imu_ctr_t.imu_t->accel.x;
    imu_ctr_t.ctr.float_data[1] = imu_ctr_t.imu_t->accel.y;
    imu_ctr_t.ctr.float_data[2] = imu_ctr_t.imu_t->accel.z;

    imu_ctr_t.ctr.float_data[3] = imu_ctr_t.imu_t->angle_rate.x;
    imu_ctr_t.ctr.float_data[4] = imu_ctr_t.imu_t->angle_rate.y;
    imu_ctr_t.ctr.float_data[5] = imu_ctr_t.imu_t->angle_rate.z;

    imu_ctr_t.ctr.float_data[6] = imu_ctr_t.imu_t->gyro.yaw;
    imu_ctr_t.ctr.float_data[7] = imu_ctr_t.imu_t->continuous_gyro.yaw;

    imu_ctr_t.ctr.float_data[8] = imu_ctr_t.imu_t->gyro.pitch;
    imu_ctr_t.ctr.float_data[9] = imu_ctr_t.imu_t->gyro.roll;

    get_protocol_send_data(IMU_USART_TX_ID,tx_flag,&imu_ctr_t.ctr.float_data[0],
                          10,send_data,&send_data_len);

    usart_send(send_data,send_data_len);
}
  • BMI088控制数据(float数据长度为0)
数据 说明
IMU_USART_ID 0X0201
bmi088_flag 16位寄存器

使用端向BMI088发送数据,详情见 串口协议文件

  • 寄存器数据打包函数
get_protocol_send_data
(0X0201,//信号id
  flag,//16位寄存器
  NULL,//待发送的float数据
  0,//float的数据长度
  usart6_tx_buf,//待发送的数据帧
  &usart6_tx_length);//待发送的数据帧长度

7. CAN方式通信

  • CAN波特率1MHZ、发送频率100Hz
  • 协议部分
  • 定义共用体变量
typedef union
{
  float data_f;
  uint8_t data_u8[4];
}data_f_u8;
  • 协议说明(单次发送-单个ID)

  • 信号数据

ID union float u8
0X301 X_ACC data_f data_u8[4]
X_RATE data_f data_u8[4]
0X302 Y_ACC data_f data_u8[4]
Y_RATE data_f data_u8[4]
0X303 Z_ACC data_f data_u8[4]
Z_RATE data_f data_u8[4]
0X304 YAW data_f data_u8[4]
YAW_C(连续) data_f data_u8[4]
0X305 pitch data_f data_u8[4]
roll data_f data_u8[4]
  • 控制数据(can有8byte,此处只使用2byte)
ID union u8
0X306 flag data_u8[8]

使用can向bmi088发送控制数据

/*设定BMI088*/
void set_can_tx_bmi088(uint16_t flag)
{
    CanTxMsg TxMessage;
    TxMessage.StdId= CAN_TX_BMI088_CMD;
    TxMessage.IDE = 0;
    TxMessage.RTR = 0;
    TxMessage.DLC = 8;
    TxMessage.Data[0] = flag >> 8;
    TxMessage.Data[1] = flag;
    TxMessage.Data[2] = 0 >> 8;
    TxMessage.Data[3] = 0;
    TxMessage.Data[4] = 0 >> 8;
    TxMessage.Data[5] = 0;
    TxMessage.Data[6] = 0 >> 8;
    TxMessage.Data[7] = 0;
    CAN_Transmit(CAN2,&TxMessage);
  }
  • BMI088模块端发送

bmi088模块端的can发送函数

void CAN_Send_Msg(uint32_t Send_StdId,float data1,float data2)
{

    static CAN_TxHeaderTypeDef  Tx_Message;
    static uint8_t              Tx_Buf[8];
    uint32_t send_mail_box;
    data_f_u8 Tx_data[2];

    Tx_Message.StdId = Send_StdId;//设置id
    Tx_Message.IDE = CAN_ID_STD;
    Tx_Message.RTR = CAN_RTR_DATA;
    Tx_Message.DLC = 0x08;

    Tx_data[0].data_f=data1;
    Tx_data[1].data_f=data2;

    for(int i=0; i<8; i++)
        {
            Tx_Buf[i]=Tx_data[i/4].data_u8[i%4];
        }
    while(HAL_CAN_AddTxMessage(&hcan1, &Tx_Message,Tx_Buf, &send_mail_box));
}
  • BMI088模块端发送函数调用

    .. code-block:: c :caption: bmi088模块端的can发送数据. :linenos:

CAN_Send_Msg(0x301,imu_ctr_t.imu_t->accel.x,imu_ctr_t.imu_t->angle_rate.x);
CAN_Send_Msg(0x302,imu_ctr_t.imu_t->accel.y,imu_ctr_t.imu_t->angle_rate.y);
CAN_Send_Msg(0x303,imu_ctr_t.imu_t->accel.z,imu_ctr_t.imu_t->angle_rate.z);
CAN_Send_Msg(0x304,imu_ctr_t.imu_t->gyro.yaw,imu_ctr_t.imu_t->continuous_gyro.yaw);
CAN_Send_Msg(0x305,imu_ctr_t.imu_t->gyro.pitch,imu_ctr_t.imu_t->gyro.roll);
  • 使用端接收示例

  • 可以使用枚举定义如下变量

bmi088模块端的can发送数据

CAN_RX_BMI088_X = 0X301,
CAN_RX_BMI088_Y = 0X302,
CAN_RX_BMI088_Z = 0X303,
CAN_RX_BMI088_YAW = 0X304,
CAN_RX_BMI088_GYRO = 0X305,
CAN_TX_BMI088_CMD = 0X306
  • 结构体

bmi088模块端的can发送数据

typedef union
{
    float data_f;
    uint8_t data_u8[4];
} data_f_u8;
typedef  struct
{
    struct
    { 
        uint8_t res:1;//<<0
        uint8_t cmd:1;//<<1
        uint8_t can_out_cmd:1;//<<2
        uint8_t usart_out_cmd:1;//<<3
        uint16_t flag;
    } imu_ctr;
    struct
    {
        float x;
        float y;
        float z;
    } acc;
    struct
    {
        float x;
        float y;
        float z;
    } rate;
    struct
    {
        float yaw;
        float pitch;
        float roll;
        float yaw_c;
    } angle;
} seasky_bmi088;
  • 数据解读

bmi088模块端的can发送数据

void get_bmi088(float *imu_1,float *imu_2,uint8_t *data)
{
  data_f_u8 rx_buf[2];
  for(int i=0; i<8; i++)
      {
          rx_buf[i/4].data_u8[i%4]=data[i];
      }
  *imu_1 = rx_buf[0].data_f;
  *imu_2 = rx_buf[1].data_f;
}
  • 对应到具体数据

can接收中断调用

void get_moto_info2(void)
{
    CanRxMsg RxMessage;
    int i;
    CAN_Receive(CAN2,CAN_FIFO0,&RxMessage);
    switch(RxMessage.StdId)
        {
        case CAN_RX_BMI088_X :
            get_bmi088x(RxMessage.Data);
            break;
        case CAN_RX_BMI088_Y :
            get_bmi088y(RxMessage.Data);
            break;
        case CAN_RX_BMI088_Z :
            get_bmi088z(RxMessage.Data);
            break;
        case CAN_RX_BMI088_YAW :
            get_bmi088_yaw(RxMessage.Data);
            break;
        case CAN_RX_BMI088_GYRO:
            get_bmi088_angle(RxMessage.Data);
            break;
        default:
            ;
            break;
        }
}

can接收中断调用.

void get_bmi088x(uint8_t *data)
{
    get_bmi088(&imu_rm.acc.x,&imu_rm.rate.x,data);
}
void get_bmi088y(uint8_t *data)
{
    get_bmi088(&imu_rm.acc.y,&imu_rm.rate.y,data);
}
void get_bmi088z(uint8_t *data)
{
    get_bmi088(&imu_rm.acc.z,&imu_rm.rate.z,data);
}
void get_bmi088_yaw(uint8_t *data)
{
    get_bmi088(&imu_rm.angle.yaw,&imu_rm.angle.yaw_c,data);
}
void get_bmi088_angle(uint8_t *data)
{
    get_bmi088(&imu_rm.angle.pitch,&imu_rm.angle.roll,data);
}
  • 接收端发送控制数据(寄存器赋值处理不完整)

can发送数据.

void imu_set(void)
{
    imu_rm.imu_ctr.flag |= imu_rm.imu_ctr.res&0x01;
    imu_rm.imu_ctr.flag |= (imu_rm.imu_ctr.cmd<<1)&0x01;
    set_can_tx_bmi088(imu_rm.imu_ctr.flag);
}

results matching ""

    No results matching ""