df_flying 发表于 2017-9-26 22:46

【MAX32630FTHR】--IIC之BMI160&OLED

本帖最后由 df_flying 于 2017-9-26 22:46 编辑

    由原理图可以看到MAX32630FTHR板载了一颗BMI160,和MAX14960同时接在了IIC2上,同时将IIC1引脚通过排针接了出来,这里正好可以接一个OLED显示。      根据所给的demo程序,其实IIC2的初始化在MAX14960初始化的时候就已经完成了,有一点不太清楚就是对应的IIC引脚并没有通过GPIO_Config()经行初始化。但为了保险这里OLED对应的IIC1的GPIO做了下简单的初始化。
      利用板载的BMI160可以方便的判断下IIC的读程序是否存在问题,也验证下IIC是否连通,代码如下
      I2CM_Read(MXC_I2CM2,BMI160_ADD,&add,1,&rec,1);
      LOG("BMI160: ID is %d\r\n",rec);
      if(rec != 209)
      {
          return -1;
      }
      后来通过BMI160的0x7e写命令后,一开始在0x0C位一直读不到数据,单步调试好像也没有发现问题,甚至可以读到160的时间戳,仔细看了下官方提供的I2CM_Write函数后,不知道是理解错了,还是...这里的函数竟然将所要写的地址作为第一个date,接上后面的数据同时写入,才是正确的,如下,不清楚封装中的cmd_data有啥用。
      data = 0x7E;//地址
      data = 0x11;//CMD
      I2CM_Write(MXC_I2CM2,BMI160_ADD,NULL,0,data,2);
   BMI初始化程序如下:      

int bmi160_Init(void)
{
      uint8_t add = 0x00,cmd= 0x00;
      uint8_t rec;
      uint8_t data;

I2CM_Read(MXC_I2CM2,BMI160_ADD,&add,1,&rec,1);
LOG("BMI160: ID is %d\r\n",rec);
      if(rec != 209)
      {
          return -1;
      }
      //acc mode
//      cmd = 0x11; //00 suspend01normal10 low power
      data = 0x7E;
      data = 0x11;
      I2CM_Write(MXC_I2CM2,BMI160_ADD,NULL,0,data,2);
HAL_Delay(100);      
      //gyr mode
      data = 0x7E;
      data = 0x15; //00 suspend 01 normal 10reserved 11 fast
      I2CM_Write(MXC_I2CM2,BMI160_ADD,NULL,0,data,2);
HAL_Delay(100);      
      //0x414g
      data = 0x41;
      data = 0x05;
      I2CM_Write(MXC_I2CM2,BMI160_ADD,NULL,0,data,2);
HAL_Delay(100);      
      //0x40
      data = 0x40;
      data = 0x29;
      I2CM_Write(MXC_I2CM2,BMI160_ADD,NULL,0,data,2);
HAL_Delay(100);      
      //0x42
      data = 0x42;
      data = 0x29;
      I2CM_Write(MXC_I2CM2,BMI160_ADD,NULL,0,data,2);
HAL_Delay(100);      
//0x43         
      data = 0x43;
      data = 0x03;
      I2CM_Write(MXC_I2CM2,BMI160_ADD,NULL,0,data,2);
HAL_Delay(100);      
      //0X7A
//      data = 0x7A;
//      data = 0x15;
//      I2CM_Write(MXC_I2CM2,BMI160_ADD,NULL,0,data,2);
//HAL_Delay(100);               
//      //0X7B
//      data = 0x7B;
//      data = 0x0b;
//      I2CM_Write(MXC_I2CM2,BMI160_ADD,NULL,0,data,2);
//HAL_Delay(100);      
      //0X41
      data = 0x41;
      data = 0x05;
      I2CM_Write(MXC_I2CM2,BMI160_ADD,NULL,0,data,2);
HAL_Delay(100);      
return 0;
}
    BMI测试程序如下:
void bmi160_Test(void)
{
uint8_t add1 = 0x0c;
      uint8_t data;
      int16_t accx,accy,accz,gyrx,gyry,gyrz;
      
I2CM_Read(MXC_I2CM2,BMI160_ADD,&add1,1,data,15);
      
      gyrx = (data<<8) |data;///13120
      gyry = (data<<8) |data;
      gyrz = (data<<8) |data;
      accx = (data<<8) |data; // /16384*2
      accy = (data<<8) |data;
      accz = (data<<8) |data;
      
      acc_x = (float) accx / 16384*2;
      acc_y = (float) accy / 16384*2;
      acc_z = (float) accz / 16384*2;
      
      gyr_x = (float) gyrx / 1312*10;
gyr_y = (float) gyry / 1312*10;
      gyr_z = (float) gyrz / 1312*10;
      
      LOG("BMI160: accx=%.4faccy=%.4faccz=%.4fgyrx=%.4fgyry=%.4fgyrz=%.4f\r\n",acc_x,acc_y,acc_z,gyr_x,gyr_y,gyr_z);
//LOG("REC = %d",rec);
      
//      uint8_t step;
//      add1=0x78;
//      I2CM_Read(MXC_I2CM2,BMI160_ADD,&add1,1,step,2);
//      LOG("step is %d\r\n",(step<<8)|step);

}

      代码中含有对BMI160step的使用,试了下好像不是很准,可能是设置的还有些问题。测试结果如下:


    OLED模块也带了不少的参考资源,这里主要是自己设置下底层函数,以及IIC1的初始化,模块上已有IIC的上啦电阻了,所以模块的两个NC上拉并不需要再焊接了。
    OLED相关底层函数以及初始化
int oled_I2cWriteCmd(uint8_t cmd)
{
      uint8_t data;
      data = OLED_CMDADD;
      data = cmd;
    if (I2CM_Write(OLED_I2CM,OLED_ADD,NULL,0,data,2) != 2) {
      return E_COMM_ERR;
    }      
      return 0;

}
/*
*
*/
int oled_I2cWriteData(uint8_t data)
{
      uint8_t wdata;
      wdata = OLED_DATAADD;
      wdata = data;
      if (I2CM_Write(OLED_I2CM,OLED_ADD,NULL,0,wdata,2) != 2) {
      return E_COMM_ERR;
    }               
      return 0;

}
const sys_cfg_i2cm_t oled_sys_cfg = {
      .clk_scale = CLKMAN_SCALE_DIV_1,
      .io_cfg = IOMAN_I2CM1(IOMAN_MAP_A, 1)
};
const gpio_cfg_t oled_iic = {PORT_3,(PIN_4 | PIN_5),GPIO_FUNC_GPIO,GPIO_PAD_OPEN_DRAIN };
/*
*
*/
void oled_Init(void)
{
//      int err=0;
                        GPIO_Config(&oled_iic);
                if((I2CM_Init(OLED_I2CM, &oled_sys_cfg, I2CM_SPEED_400KHZ))!= E_NO_ERROR)
                {
                        printf("I2C1 err \r\n");
                }
HAL_Delay(200);
测试结果如图:

      直接上代码了,也方便以后自己查找,见附件
页: [1]
查看完整版本: 【MAX32630FTHR】--IIC之BMI160&OLED