BMI055编程

BMI055与其他imu不同的地方是他的加速度硬件单元和陀螺仪硬件单元是分开独立的(两个不同的CHIPID),他们使用两个不同的片选,地址空间重叠。

一般的imu如 mpu6050,mpu6500,mpu9250,imu160等等都是加速度硬件单元和陀螺仪硬件单元一体,一个片选,地址不重叠。
所以BMI055的编程稍微复杂点,需要两个spi,如果共用GPIO的话那就至少需要一个IO口模拟的spi(1硬件1模拟或者2个模拟)。
代码如下:

#include "imu.h"

void IMU_init(void)
{   
    u8 imu_data[12] = {0};
    u16 imu_dat[6] = {0};

    my_spi_io_init();
    IMU_config(RANGE_2G,RANGE_2000);
    while(1){//for test
      IMU_Read(imu_data);
      //acc
      imu_dat[0] = (u16)imu_data[1]<<4 | imu_data[0]>>4;
      imu_dat[1] = (u16)imu_data[3]<<4 | imu_data[2]>>4;
      imu_dat[2] = (u16)imu_data[5]<<4 | imu_data[4]>>4;
      //gyr
      imu_dat[3] = imu_data[7]<<8  | imu_data[6];
      imu_dat[4] = imu_data[9]<<8  | imu_data[8];
      imu_dat[5] = imu_data[11]<<8 | imu_data[10];
      asm("nop");
    }
}

void IMU_Read(u8 *buf)
{
    u8 i = 0;
    u8 addr = 0x00; 
    addr |= 0x80;//read
    //read acc data
    SPI_CS_ACC = 0;
    addr |= ACC_X_LSB_REG;
    My_SPI_ReadWriteByte(addr);
    for(i=0;i<6;i++){
        *(buf+i) = My_SPI_ReadWriteByte(0);     
        asm("nop");
    }
    SPI_CS_ACC = 1;
    //read gyr data
    SPI_CS_GYR = 0;
    addr |= GYR_X_LSB_REG;
    My_SPI_ReadWriteByte(addr);
    for(i=6; i<12; i++){
        *(buf+i) = My_SPI_ReadWriteByte(0);     
        asm("nop");
    }
    SPI_CS_GYR = 1;
}
//   for(i=0;i<6;i++){
//        SPI_CS_ACC=0;
//        addr |= (ACC_X_LSB_REG+i);
//        RW_SPI(addr);
//        acc[i] = RW_SPI(0);       
//        SPI_CS_ACC=1;
//    } 

u8 My_SPI_ReadWriteByte(u8 val)
{
    u8 i;
    for(i=0;i<8;i++){ 
        SPI_CLK = 0;
        asm("nop"); asm("nop"); asm("nop");
        //write
        if(val & 0x80)                                
            SPI_DO = 1;
        else
            SPI_DO = 0;
        val <<= 1;
        SPI_CLK = 1;
        asm("nop"); asm("nop"); asm("nop");
        //read
        if(SPI_DI)
            val |= 1;                                       
    }
    SPI_CLK = 0;    
    return val;
}

u8  IMU_config(u8 acc_range,u8 gyr_range)
{
    u8 res = 0;
    u8 reg = 0x00;//REG_CHIPID 
    reg |= 0x80;//read    

    //Check ACC CHIP_ID
    SPI_CS_ACC=0;
    My_SPI_ReadWriteByte(reg);          
    res = My_SPI_ReadWriteByte(0);      
    SPI_CS_ACC=1;
    if(res != ACC_CHIP_ID){
        res = 1;
    }
    //Check GYR CHIP_ID
    SPI_CS_GYR=0;
    My_SPI_ReadWriteByte(reg);          
    res = My_SPI_ReadWriteByte(0);      
    SPI_CS_GYR=1;
    if(res != GYR_CHIP_ID){
        res = 2;
    }   
    //Config ACC RANGE
    SPI_CS_ACC=0;
    My_SPI_ReadWriteByte(IMU_CONFIG_REG);//write            
    My_SPI_ReadWriteByte(acc_range);
    SPI_CS_ACC=1;
    SPI_CS_ACC=0;
    My_SPI_ReadWriteByte(reg | IMU_CONFIG_REG);         
    res = My_SPI_ReadWriteByte(0);//read reg 
    if(res != acc_range){//Write failed.
        res = 3;
    }
    SPI_CS_ACC=1;   
    //Config GYR RANGE
    SPI_CS_GYR=0;
    My_SPI_ReadWriteByte(IMU_CONFIG_REG);//write            
    My_SPI_ReadWriteByte(gyr_range);
    SPI_CS_GYR=1;
    SPI_CS_GYR=0;
    My_SPI_ReadWriteByte(reg | IMU_CONFIG_REG);         
    res = My_SPI_ReadWriteByte(0);//read reg 
    if(res != gyr_range){//Write failed.
        res = 4;
    }else{
        res = 0;//ok
    }
    SPI_CS_GYR=1; 
    return res;
}  


void my_spi_io_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;        
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE );//PORTB奀笘妏夔 

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13 |  GPIO_Pin_15;//sck,miso
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);    
    GPIO_SetBits(GPIOB, GPIO_Pin_13 |  GPIO_Pin_15);  

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_14 ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //MOSI  input
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    //PA4: CS_ACC
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_4);

    //PB12: CS_GYR
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_SetBits(GPIOB,GPIO_Pin_12);    
}

你可能感兴趣的:(VR/AR)