一周搞定9轴MPU9250(无华)(3)--数据采集

数据采集主要是调通IIC,MPU9250比较坑的一点是他的地磁计的数据采集,网上不少人也有这个问题。有了上一节所说的stm32cube生成的代码,使用它的库函数很好实现IIC数据的收发 。函数

主要是调用HAL_I2C_Mem_Write()进行数据写,HAL_I2C_Mem_Read()进行数据读。这时能够对传感器进行读写操做。首先咱们调通mpu9250的mpu6500,也即陀螺仪和加速度计。ui

使用下面一段程序进行模块的初始化。it

 

void MPU_INIT(void)循环

{float

HAL_I2C_Mem_Read( &hi2c1, 0xD0,0x75,1,wrbuf, 1,20);程序

//读ID,确认IIC可以使用数据采集

if(wrbuf[0] != 0x71)数据

{co

return;采集

}

HAL_Delay(500);

WriteReg(MPU6500_I2C_ADDR,MPU6500_CONFIG,MPU_GYRO_LPS_184HZ);

WriteReg(MPU6500_I2C_ADDR,MPU6500_GYRO_CONFIG,MPU_GYRO_FS_500);

WriteReg(MPU6500_I2C_ADDR,MPU6500_ACCEL_CONFIG,MPU_ACCE_FS_8G);

WriteReg(MPU6500_I2C_ADDR,MPU6500_SMPLRT_DIV,0x07); //125HZ 1000/(1+7)

WriteReg(MPU6500_I2C_ADDR,MPU6500_ACCEL_CONFIG_2,MPU_ACCE_LPS_460HZ);

WriteReg(MPU6500_I2C_ADDR,MPU6500_INT_PIN_CFG,0x02); //turn on Bypass Mode

HAL_I2C_Mem_Read( &hi2c1, AK8963_I2C_ADDR, AK8963_WIA,1, wrbuf, 1,20);

if(wrbuf[0] != 0x48)

{

return;

}

WriteReg(AK8963_I2C_ADDR ,AK8963_CNTL1,0x02); //continuous mode1

 

}

 

void WriteReg(u8 addr,u8 reg,uint8_t data)

{

HAL_I2C_Mem_Write(&hi2c1, addr, reg, 1, &data, 1, 20);

}

 

初始化完成以后,就能够使用IIC循环读数据寄存器了。数据寄存器为

#define MPU6500_GYRO_XOUT_H ((u8)0x43)

#define MPU6500_GYRO_XOUT_L ((u8)0x44)

#define MPU6500_GYRO_YOUT_H ((u8)0x45)

#define MPU6500_GYRO_YOUT_L ((u8)0x46)

#define MPU6500_GYRO_ZOUT_H ((u8)0x47)

#define MPU6500_GYRO_ZOUT_L ((u8)0x48)

 

#define MPU6500_ACCEL_XOUT_H 0x3B //????????

#define MPU6500_ACCEL_XOUT_L 0x3C

#define MPU6500_ACCEL_YOUT_H 0x3D

#define MPU6500_ACCEL_YOUT_L 0x3E

#define MPU6500_ACCEL_ZOUT_H 0x3F

#define MPU6500_ACCEL_ZOUT_L 0x40

 

对寄存器进行读便可。这里介绍一下这个库函数HAL_I2C_Mem_Read,它能够指定读数据的长度,而且能够指定读地址的长度,是一个比较好用的库函数。咱们直接调用它进行读操做便可,

HAL_I2C_Mem_Read( &hi2c1, 0xD0,GYRO_XOUT_H,1, wrbuf, 6,20);

而后对数据进行如下转换就能够获得数据。

比较坑的是地磁计AK8963的数据读取。咱们这里使用bypass模式对地磁传感器进行读操做,它必须对状态寄存器进行读操做,才能获得正确的数值,不然只能读取到第一次的值,之后就不改变。

void READ_MPU9250_MAG(void)

{

memset(wrbuf,0,6);

// WriteReg(MPU6500_I2C_ADDR,MPU6500_INT_PIN_CFG,0x02); //turn on Bypass Mode

HAL_I2C_Mem_Read( &hi2c1, AK8963_I2C_ADDR, AK8963_ST1,1, wrbuf, 1,20);

if( (wrbuf[0]&0x03))

{

HAL_I2C_Mem_Read( &hi2c1, AK8963_I2C_ADDR, AK8963_HXL,1, wrbuf, 6,20);

memcpy(&mpurdata,wrbuf,6);

mag.x = MPU_MAGN_K*(float)mpurdata.x;

mag.y = MPU_MAGN_K*(float)mpurdata.y;

mag.z = MPU_MAGN_K*(float)mpurdata.z;

}

HAL_I2C_Mem_Read( &hi2c1, AK8963_I2C_ADDR, AK8963_ST2,1, wrbuf, 1,20);

// ExchangeBuf(wrbuf);

}

 

上面是低地磁计的读取函数,能够看到,在连续读模式下,咱们必须对其AK8963_ST2这个寄存器进行读操做才能获得正确的数值。

完成程序的编写以后,咱们能够获得正确的数值。