OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5579|回复: 1

关于MPU9250的SPI读写问题

[复制链接]

27

主题

81

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
411
金钱
411
注册时间
2014-4-18
在线时间
94 小时
发表于 2017-9-5 09:10:40 | 显示全部楼层 |阅读模式
20金钱
现在用SPI读写9250,但是存在一些问题,一个是读WHO_AM_I的时候偶尔会读成0x70(正常是0x71)但是关机过一会在开又没问题了,小概率事件。
再就是读取加速度和角速度的时候加速度计只有Y和Z轴有变化,虽然有线性变化但是按照手册上的方向倾斜没反映,X轴直接没有任何数据变化,一直是-32768但是有时候倾斜Y轴大的时候也会有很小的变化。
代码如下:
初始化:
[mw_shl_code=c,true]//初始化SPI总线
void SPI_INIT(void)
{
  SPI_InitTypeDef  SPI_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
        GPIO_QuickInit(GPIOB,GPIO_Pin_2,GPIO_Mode_Out_PP);//MPU CS
        GPIO_QuickInit(GPIOA,GPIO_Pin_8,GPIO_Mode_Out_PP);//MS5611 CS
        PAout(8) = 1;
        PBout(2) = 1;
        /*SCK,MISO,MOSI引脚,GPIOA^5,GPIOA^6,GPIOA^7 */
        GPIO_QuickInit(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7,GPIO_Mode_AF_PP);
        GPIO_SetBits(GPIOB,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
        GPIO_SetBits(GPIOB,GPIO_Pin_2);
        GPIO_SetBits(GPIOA,GPIO_Pin_8);
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;        //双线全双工
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                                                                                                //主模式
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                                                                                //数据大小8位
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                                                                                                        //时钟极性,空闲时为高
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;                                                                                                //第1个边沿有效,上升沿为采样时刻
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                                                                                                                //NSS信号由软件产生
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                                                                        //高位在前
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI1, &SPI_InitStructure);
  SPI_Cmd(SPI1, ENABLE);
}[/mw_shl_code]
SPI读写:
[mw_shl_code=c,true]uint8_t SPI_RW(uint8_t dat)
{         
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPI1, dat);               
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
  return SPI_I2S_ReceiveData(SPI1);
}
uint8_t SPI_MPU_SingleWriteReg(uint8_t reg,uint8_t dat)
{
        uint8_t status;
        PBout(2) = 0;//选择MPU
        status = SPI_RW(reg);
        SPI_RW(dat);
        PBout(2) = 1;
        return(status);
}

uint8_t SPI_MPU_SingleReadReg(uint8_t reg)
{
        uint8_t reg_val;
        PBout(2) = 0;//选择MPU
        SPI_RW(reg|READ_FLAG);
        reg_val = SPI_RW(0x00);
        PBout(2) = 1;
        return reg_val;
}

void SPI_MPU_ReadReg(uint8_t start_reg,uint8_t *datas,uint8_t len)
{
        PBout(2) = 0;//选择MPU
        DelayUs(100);
        SPI_RW(start_reg|READ_FLAG);
        DelayUs(100);
        for(uint8_t i=0;i<len;i++)
                datas = SPI_RW(0x00);
        PBout(2) = 1;
}[/mw_shl_code]

MPU9250初始化:
[mw_shl_code=c,true]uint8_t mpu_init(void)
{
        uint8_t ack;
        DelayMs(200);
        SPI_INIT();//初始化SPI总线
        DelayMs(200);
        ack = SPI_MPU_SingleReadReg(WHO_AM_I_MPU9250);
        if(ack == 0x71)
        {
                printf("GYR ACC OK!\r\n");
                SPI_MPU_SingleWriteReg(PWR_MGMT_1                ,0X80);                                                                        //解除休眠模式
                DelayMs(200);
                SPI_MPU_SingleWriteReg(PWR_MGMT_1                ,0X00);                                                                        //解除休眠模式
                SPI_MPU_SingleWriteReg(USER_CTRL                ,0x30);                                                                        //进入SPI模式(bit4)  开启I2C Master模式(bit5)
                SPI_MPU_SingleWriteReg(SMPLRT_DIV                ,0x00);                                                                        //采样率1000/(1+0)=1000HZ
                SPI_MPU_SingleWriteReg(CONFIG                                ,MPU9250_DLPF_BW_3600);        //低通滤波 3600hz - 0.17ms Delay
                SPI_MPU_SingleWriteReg(GYRO_CONFIG        ,MPU9250_GYRO_FS_1000);        //陀螺仪测量范围 +-1000
                SPI_MPU_SingleWriteReg(ACCEL_CONFIG        ,MPU9250_ACCEL_FS_4);                //加速度计测量范围 +-4G
                SPI_MPU_SingleWriteReg(ACCEL_CONFIG2,0x08);                                                                        //加速度计滤波频率 1.13K
                return TRUE;
        }
        printf("GYR ACC Fail-0x%02X\r\n",ack);
        return FALSE;
}[/mw_shl_code]
测试读写:
[mw_shl_code=c,true]        short temp[3];
        uint8_t mpu_buffer[14];
        SPI_MPU_ReadReg(0x3B,mpu_buffer,14);

        temp[0] = (mpu_buffer[0] << 8) | mpu_buffer[1];
        temp[1] = (mpu_buffer[2] << 8) | mpu_buffer[3];
        temp[2] = (mpu_buffer[4] << 8) | mpu_buffer[5];
        sensor_mpu.acc.quiet.x = 0;
        sensor_mpu.acc.quiet.y = 0;
        sensor_mpu.acc.origin.x = temp[0] - sensor_mpu.acc.quiet.x;
        sensor_mpu.acc.origin.y = temp[1] - sensor_mpu.acc.quiet.y;
        sensor_mpu.acc.origin.z = temp[2];

        sensor_mpu.gyr.origin.x = ((((int16_t)mpu_buffer[8]) << 8) | mpu_buffer[9]);
        sensor_mpu.gyr.origin.y = ((((int16_t)mpu_buffer[10]) << 8)| mpu_buffer[11]);
        sensor_mpu.gyr.origin.z = ((((int16_t)mpu_buffer[12]) << 8)| mpu_buffer[13]);
       
        sensor_mpu.gyr.radian.x=sensor_mpu.gyr.origin.x-sensor_mpu.gyr.quiet.x;
        sensor_mpu.gyr.radian.y=sensor_mpu.gyr.origin.y-sensor_mpu.gyr.quiet.y;
        sensor_mpu.gyr.radian.z=sensor_mpu.gyr.origin.z-sensor_mpu.gyr.quiet.z;

        printf("%d        %d        %d                        %d        %d        %d\r\n",sensor_mpu.gyr.origin.x,sensor_mpu.gyr.origin.y,sensor_mpu.gyr.origin.z,
        sensor_mpu.acc.origin.x,sensor_mpu.acc.origin.y,sensor_mpu.acc.origin.z);[/mw_shl_code]

最佳答案

查看完整内容[请看2#楼]

问题解决了,可能是焊接温度太高了(风枪300℃)也可能是超声波清洗时候的问题,后来换了一个IC用250℃吹上后测试没问题,但是又用超声波洗了一下之后X轴的加速度一直是负的(但是有线性变化),总之陀螺仪是没问题了。。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

27

主题

81

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
411
金钱
411
注册时间
2014-4-18
在线时间
94 小时
 楼主| 发表于 2017-9-5 09:10:41 | 显示全部楼层
问题解决了,可能是焊接温度太高了(风枪300℃)也可能是超声波清洗时候的问题,后来换了一个IC用250℃吹上后测试没问题,但是又用超声波洗了一下之后X轴的加速度一直是负的(但是有线性变化),总之陀螺仪是没问题了。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-18 07:52

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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