搜索
bottom↓
回复: 6

mpu9255九轴数据读取详细讲解

[复制链接]

出0入0汤圆

发表于 2016-3-5 20:47:24 | 显示全部楼层 |阅读模式
本帖最后由 yangjiajiang 于 2016-3-5 21:05 编辑

转载自EEBOARD——湛无双——GD32F207E+MPU9255数据读取

本次实验的目的在于能够读取到MPU9255的原始数据,后面还有帖子进行数据融合,今天主要内容是使用GD32F207ZE红板子进行开发,先是编写IIC程序,然后读取DATASHEET进行参数设置,并读取原始数据显示出来。
首先,感谢爱板网提供的这次机会,让我能够使用上国产的GD32F207板子,总体来说,拿到板子感觉做工很精致,并且外观也不错,唯一有点缺陷的是为了更好的发挥板子的性能,没有使用到Arduino接口,不过这都没关系,后面会有扩展板发来,本人属于第二批的名单,不晓得什么时候能收到,不过这完全不影响我读取MPU9255原始数据。
MPU9255集成了三轴加速度传感器,三轴陀螺仪和三轴磁力计。其中三轴磁力计是采用片内集成AK8963的方式实现的,这也导致了写程序的时候不仅仅要操作一个芯片,其实要操作两个芯片,虽然只有一个芯片。
一、MPU9255硬件原理图

这个是买到的MPU9255的原理图,其实这个原理图中比较中的部分是接口定义和电源电压供应,可以看到模块把主要的接口都给引了出来,那么本次实验既然使用到了IIC接口,那就只用里面的SDA和SCL吧~。
其次是原理图中的电源供应问题,根据芯片手册所提及的电源供给电压,里面是这么说的:

可以看到供给电压在2.4V~3.6V的范围,但是模块上已经集成了电压稳压模块,那就直接使用好了,如果外部电压采用3.3V,可以使用短路模块上的焊盘来实现低电压的输入,使用起来很方便,本次实验就是使用了这种方式。
二、MPU9255软件编写
①查看MPU9255的设备地址
手册上所参考的I2C地址受外部引脚的控制,所购买的模块上已经把AD0强行拉低了,那么I2C设备地址为1101000,在实际的读写过程中需要进行读写,第八位表示读写,那么写的地址为11010000,读的地址为11010001,就可以说模拟I2C中地址为0xd0,这在后面的编写中是很重要的。
②查看相关寄存器
在进行I2C调制之前,比较重要的一步是读取I2C设备的设备ID,这样就可以知道我们调试的I2C是否已经成功了,同时也可以查看设备是否存在,根据手册上所说的,设备ID名字为WHO AM I寄存器,通过读取这个寄存器可以返回一个固定值。

这个固定值为0x73,在这里需要提一句的是上电之初需要想电源管理寄存器写入0x00来启动设备,这一点是比较重要的。
那么我们就可以借此编写代码,其中I2C底层的协议不再赘述。
MPU_Write(MPU9255_ADDR,PWR_MGMT_1,0x00);

Delay_1ms(10);
i2c_dev=MPU_Read(MPU9255_ADDR,WHO_AM_I);
在这个代码里面,我们开启了MPU9255,并且读取了设备寄存器,如果我们读取到的i2c_dev值为0x73,那就说明读取成功了,可以进行下一步的操作。
③读取三轴加速度和三轴陀螺仪
在具体的操作中,还需要设置采样率,量程范围,不过这里不再说那些,先直接告诉大家怎么用,还是看手册,手册里面写了三轴加速度和三轴陀螺仪的数据地址。

手册上所述的地址如图所示,可以看到MPU9255还包含了温度测量功能,不过咱们目前用不到,还是不要管了,记得本科上传感器技术的老师说过有的传感器里面包含有温度测量功能,这个功能是用来校正传感器自身的温度漂移,实现传感器在温度上的校正,具体怎么操作也没有说,那么就算了。
这样也就可以编写出来读取三轴加速度和三轴陀螺仪的函数了,这里使用了连续多个读取的方式,节省了时间提高了效率。
void MPU9255_ReadAccel(ACCEL_TypeDef *ACCEL_Struct)
{
        u8 AccelTable[6];
        
        MPU_Reads(MPU9255_ADDR,ACCEL_XOUT_H,AccelTable,6);
        
        ACCEL_Struct->accel_x = ((u16)AccelTable[0])<<8 | AccelTable[1];
        ACCEL_Struct->accel_y = ((u16)AccelTable[2])<<8 | AccelTable[3];
        ACCEL_Struct->accel_z = ((u16)AccelTable[4])<<8 | AccelTable[5];
        
}
void MPU9255_ReadGyro(GYRO_TypeDef *GYRO_Struct)
{
        u8 GyroTable[6];
        
        MPU_Reads(MPU9255_ADDR,GYRO_XOUT_H,GyroTable,6);
        
        GYRO_Struct->gyro_x = ((u16)GyroTable[0])<<8 | GyroTable[1];
        GYRO_Struct->gyro_y = ((u16)GyroTable[2])<<8 | GyroTable[3];
        GYRO_Struct->gyro_z = ((u16)GyroTable[4])<<8 | GyroTable[5];
}
上面的函数就完成了数据的读取了,到了这里大家可能疑惑三轴磁力计怎么没有,上面给大家说过了,三轴磁力计是MPU9255模块里面的另一个,需要特别的方式读取,那么我们就需要慢慢来分析。
④三轴磁力计数据读取
同样下载了AK8963的手册,看手册里面是怎么说的。不过在读取之前需要将MPU9255设置为BYPASS MODE,怎么设置这个呢?有一个专门的寄存器可以完成。

就是这个55寄存器,十六进制值为0x37,只要他的位1设置为一就可以了,所以在读取钱需要向0x37寄存器写入0x02,至于其他位咱们就不管了。
三轴磁力计AK8963的I2C设备地址在手册里面是这么叙述的:

分别是00011xxx,这个xxx咱们直接设置为0好了,那么8位地址就是0x18了,很好的一个地方是AK8963也有设备ID,我们可以读取到,直接读取AK8963的寄存器0x00就可以得到设备ID,值为0x48,这个如下面这个图:

那么程序里面就可以这么写:
MPU_Write(MPU9255_ADDR,INT_PIN_CFG,0x02);//进入Bypass模式,用于控制电子指南针
i2c_dev = MPU_Read(MAG_ADDR,MAG_WIA);
if(i2c_dev == MAG_ID)
{
        MPU_Write(MAG_ADDR,MAG_CNTL1,0x01);
        return 0;
}
直接读取ID看是否匹配,就可以查看方法是不是对的。我也是这个认为的,如果是对的,就可以启动单次数据转换了。
在读取三轴磁力计数据的时候,写好的函数是这样的:
void MPU9255_ReadMag(MAG_TypeDef *MAG_Struct)
{
        u8 MagTable[6];
        
//        MPU_Write(MAG_ADDR,MAG_CNTL1,0x01);
//        Delay_1ms(10);
        MPU_Reads(MAG_ADDR,MAG_XOUT_L,MagTable,6);
        MPU_Write(MAG_ADDR,MAG_CNTL1,0x01);
        
        MAG_Struct->mag_x = ((u16)MagTable[1])<<8 | MagTable[0];
        MAG_Struct->mag_y = ((u16)MagTable[3])<<8 | MagTable[2];
        MAG_Struct->mag_z = ((u16)MagTable[5])<<8 | MagTable[4];
        
}
这个里面的MAG_CNTL1是用来启动单次数据转换的,千万要记住,如果不加这句话,下次读取会发现三轴磁力计的数据是不会变的,切记切记。
三、主函数的调用
主函数的调用无非是查看设备是否存在,如果存在的话,就开始循环读取数据,并发送给电脑,我也是这么编写的。
int main(void)
{
        ACCEL_TypeDef ACCEL_TypeStructure;
        GYRO_TypeDef GYRO_TypeStructure;
        MAG_TypeDef MAG_TypeStructure;
        
    LED_config();
    SysTick_Configuration();
        USART1_Init(115200);
        
        switch(MPU9255_Init())
        {
        case 1:
                while(1)
                {
                        GPIOD->DOR ^= GPIO_PIN_11;
                        Delay_1ms(500);
                }
        case 2:
                while(1)
                {
                        GPIOD->DOR ^= GPIO_PIN_12;
                        Delay_1ms(300);
                }
        case 0:
                break;
        default:
                while(1);
        }
        
    while (1)
   {
                Delay_1ms(200);
                MPU9255_ReadAccel(&ACCEL_TypeStructure);
                MPU9255_ReadGyro(&GYRO_TypeStructure);
                MPU9255_ReadMag(&MAG_TypeStructure);
                u1_printf("ACCEL=>X:%d,Y:%d,Z:%d\r\n",ACCEL_TypeStructure.accel_x,ACCEL_TypeStructure.accel_y,ACCEL_TypeStructure.accel_z);
                u1_printf("GYRO=>X:%d,Y:%d,Z:%d\r\n",GYRO_TypeStructure.gyro_x,GYRO_TypeStructure.gyro_y,GYRO_TypeStructure.gyro_z);
                u1_printf("MAG=>X:%d,Y:%d,Z:%d\r\n",MAG_TypeStructure.mag_x,MAG_TypeStructure.mag_y,MAG_TypeStructure.mag_z);
                u1_printf("****************************\r\n");
                GPIOD->DOR ^= GPIO_PIN_13;
   }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2016-3-5 21:03:19 | 显示全部楼层
mpu9255手册与ARM读取程序

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2016-3-5 21:03:52 | 显示全部楼层
大赞楼主

出0入0汤圆

发表于 2016-3-5 21:13:27 | 显示全部楼层
mark ,正打算继续搞搞9250 ,谢楼主。

出0入0汤圆

发表于 2016-3-5 22:51:58 | 显示全部楼层
我都是用连续模式读磁力计的。

出0入0汤圆

发表于 2016-3-6 16:36:55 | 显示全部楼层
用同步方式读取低速通信的传感器有点奢侈

出0入0汤圆

发表于 2016-3-7 18:25:39 | 显示全部楼层
DA ZAN LOU ZHU A !
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 23:45

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表