【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]