关于MPU9250的SPI读写问题

2019-07-20 12:08发布

现在用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! ");
                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 ",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 ",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]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。