MPU9250 无数据

2019-07-21 03:33发布

自己做课题做的一块板子,MCU选用的是stm32f103c8t6 集成MPU9250 和另外一个芯片
调试到mpu9250时候 ,在keil上调试 加速度、角速度以及磁力计是有数据的。用到的就是论坛里分享的开源代码--> http://www.openedv.com/forum.php ... id=80200&page=1
接下来焊接上另外一个芯片后,这个芯片与stm32也调试通了的。
但是,回过头来 准备做mpu9250的九轴融合时候,加速度、角速度和磁力计的数据都变为零了......
不知道有没有人遇到过这种情况?

说明:mpu9250用spi2连接的
      另外的那个芯片用的是spi1

另外那个芯片从焊接到调通用了1晚上的时间,第二天早上来调试mpu9250就没数据了
mpu9250的引脚已经测试过了 都是连接着的呀
mpu9250与stm32的程序 与 另外芯片和stm32程序 是放在两个文件夹下的 分开放的 还没有融合在一起

烦请各位大佬看下



这个是spi.c文件

[mw_shl_code=c,true]#include "spi.h"
typedef struct{
        short Accel[3];//Accel X,Y,Z
        short Gyro[3];//Gyro X,Y,Z
        short Mag[3];        //Mag X,Y,Z       
}MPU_value;
MPU_value mpu_value;
//MPU_value *mpu_value=NULL;          //9轴数据--------------修改
unsigned char BUF[6];       //接收数据缓存区
short Data_Buf[9];        
/***************************************************************/
void spi_Init()
{
        SPI_InitTypeDef SPI_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;
       
//        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1|RCC_APB2Periph_GPIOA, ENABLE);       

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
       
       
        //GPIO口配置设置//
//        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
       
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
// GPIO_Init(GPIOA, &GPIO_InitStructure);
//        GPIO_SetBits(GPIOA,GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7);
       
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
       
       
    /*Configure PA.4(NSS)--------------------------------------------*/
//  GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0;
//  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
//  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//  GPIO_Init(GPIOA, &GPIO_InitStructure);
//        GPIO_SetBits(GPIOA,GPIO_Pin_0);
        /*片选设置  PB12*/
        GPIO_InitStructure.GPIO_Pin =GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_12);
       
       
       
       
       
       
       
         /* SPI2 configuration */
  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_CPOL_High=模式3,时钟空闲为高 //SPI_CPOL_Low=模式0,时钟空闲为低
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//SPI_CPHA_2Edge;//SPI_CPHA_1Edge, SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//SPI_NSS_Soft;//SPI_NSS_Hard
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;//SPI_BaudRatePrescaler_2=32M;//SPI_BaudRatePrescaler_4=18MHz
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//数据从高位开始发送
  SPI_InitStructure.SPI_CRCPolynomial = 7;
       
//        SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
//        SPI_Cmd(SPI1, ENABLE); //使能SPI外设

  SPI_Init(SPI2, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
        SPI_Cmd(SPI2, ENABLE); //使能SPI外设



}
/***************************************************************/
//SPIx
//TxData:发送一个字节
//返回值:data
/***************************************************************/
static u8 SPI2_ReadWriteByte(u8 TxData)//static u8 SPI1_ReadWriteByte(u8 TxData)
{               
        u8 retry=0;                                        
        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //等待SPI发送标志位空   修改
                {
                retry++;
                if(retry>200)return 0;
                }                          
        SPI_I2S_SendData(SPI2, TxData); //发送数据   修改
        retry=0;

        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //等待SPI接收标志位空  修改
                {
                retry++;
                if(retry>200)return 0;
                }                                                              
        return SPI_I2S_ReceiveData(SPI2); //接收数据                  修改                            
}
/***************************************************************/
//SPI发送
//reg: addr
//value:数据
/***************************************************************/
u8 MPU9250_Write_Reg(u8 reg,u8 value)
{
        u8 status;
                MPU_9250_ENABLE;   //        MPU9250_CS=0;  //片选MPU9250
        status=SPI2_ReadWriteByte(reg); //发送reg地址
        SPI2_ReadWriteByte(value);//发送数据
        MPU_9250_DISENABLE;//        MPU9250_CS=1;  //失能MPU9250
        return(status);//
}
//---------------------------------------------------------------//
//SPI读取
//reg: addr
u8 MPU9250_Read_Reg(u8 reg)
{
          u8 reg_val;
                MPU_9250_ENABLE;//        MPU9250_CS=0;  //片选MPU9250
          SPI2_ReadWriteByte(reg|0x80); //reg地址+读命令
          reg_val=SPI2_ReadWriteByte(0xff);//任意数据
                MPU_9250_DISENABLE;//        MPU9250_CS=1;  //失能MPU9250
        return(reg_val);
}
/***************************************************************/
// MPU内部i2c 写入
//I2C_SLVx_ADDR:  MPU9250_AK8963_ADDR
//I2C_SLVx_REG:   reg
//I2C_SLVx_Data out:  value
/***************************************************************/
static void i2c_Mag_write(u8 reg,u8 value)
{
        u16 j=500;
        MPU9250_Write_Reg(I2C_SLV0_ADDR ,MPU9250_AK8963_ADDR);//设置磁力计地址,mode: write
        MPU9250_Write_Reg(I2C_SLV0_REG ,reg);//set reg addr
        MPU9250_Write_Reg(I2C_SLV0_DO ,value);//send value       
        while(j--);//此处因为MPU内部I2C读取速度较慢,延时等待内部写完毕
}
/***************************************************************/
// MPU内部i2c 读取
//I2C_SLVx_ADDR:  MPU9250_AK8963_ADDR
//I2C_SLVx_REG:   reg
//return value:   EXT_SENS_DATA_00 register value
/***************************************************************/
static u8 i2c_Mag_read(u8 reg)
{
        u16 j=5000;
        MPU9250_Write_Reg(I2C_SLV0_ADDR ,MPU9250_AK8963_ADDR|0x80); //设置磁力计地址,mode:read
        MPU9250_Write_Reg(I2C_SLV0_REG ,reg);// set reg addr
        MPU9250_Write_Reg(I2C_SLV0_DO ,0xff);//read
        while(j--);//此处因为MPU内部I2C读取速度较慢,必须延时等待内部读取完毕
        return MPU9250_Read_Reg(EXT_SENS_DATA_00);
}

//****************初始化MPU9250,根据需要请参考pdf进行修改************************
void Init_MPU9250(void)
{       
        MPU9250_Write_Reg(PWR_MGMT_1, 0x00);        //解除休眠状态
        MPU9250_Write_Reg(CONFIG, 0x07);      //低通滤波频率,典型值:0x07(3600Hz)此寄存器内决定Internal_Sample_Rate==8K
       
/**********************Init SLV0 i2c**********************************/       
//Use SPI-bus read slave0
        MPU9250_Write_Reg(INT_PIN_CFG ,0x30);// INT Pin / Bypass Enable Configuration  
        MPU9250_Write_Reg(I2C_MST_CTRL,0x4d);//I2C MAster mode and Speed 400 kHz
        MPU9250_Write_Reg(USER_CTRL ,0x20); // I2C_MST _EN
        MPU9250_Write_Reg(I2C_MST_DELAY_CTRL ,0x01);//延时使能I2C_SLV0 _DLY_ enable        
        MPU9250_Write_Reg(I2C_SLV0_CTRL ,0x81); //enable IIC        and EXT_SENS_DATA==1 Byte
       
/*******************Init GYRO and ACCEL******************************/       
        MPU9250_Write_Reg(SMPLRT_DIV, 0x07);  //陀螺仪采样率,典型值:0x07(1kHz) (SAMPLE_RATE= Internal_Sample_Rate / (1 + SMPLRT_DIV) )
        MPU9250_Write_Reg(GYRO_CONFIG, 0x18); //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
        MPU9250_Write_Reg(ACCEL_CONFIG, 0x18);//加速计自检、测量范围及高通滤波频率,典型值:0x18(不自检,16G)
        MPU9250_Write_Reg(ACCEL_CONFIG_2, 0x08);//加速计高通滤波频率 典型值 :0x08  (1.13kHz)       
               
/**********************Init MAG **********************************/
        i2c_Mag_write(AK8963_CNTL2_REG,AK8963_CNTL2_SRST); // Reset AK8963
        i2c_Mag_write(AK8963_CNTL1_REG,0x12); // use i2c to set AK8963 working on Continuous measurement mode1 & 16-bit output       
}

//************************加速度读取**************************--------修改/
//void READ_MPU9250_ACCEL(void)//
//{

//   BUF[0]=MPU9250_Read_Reg(ACCEL_XOUT_L);
//   BUF[1]=MPU9250_Read_Reg(ACCEL_XOUT_H);
//   mpu_value.Accel[0]=        (BUF[1]<<8)|BUF[0];
//   mpu_value.Accel[0]/=164;                                                    //读取计算X轴数据
//   BUF[2]=MPU9250_Read_Reg(ACCEL_YOUT_L);
//   BUF[3]=MPU9250_Read_Reg(ACCEL_YOUT_H);
//   mpu_value.Accel[1]=        (BUF[3]<<8)|BUF[2];
//   mpu_value.Accel[1]/=164;                                                    //读取计算Y轴数据
//   BUF[4]=MPU9250_Read_Reg(ACCEL_ZOUT_L);
//   BUF[5]=MPU9250_Read_Reg(ACCEL_ZOUT_H);
//   mpu_value.Accel[2]=  (BUF[5]<<8)|BUF[4];
//   mpu_value.Accel[2]/=164;                                               //读取计算Z轴数据
//}


void READ_MPU9250_ACCEL(void)
{  
          
   BUF[0]=MPU9250_Read_Reg(ACCEL_XOUT_L);
   BUF[1]=MPU9250_Read_Reg(ACCEL_XOUT_H);
   mpu_value.Accel[0]=        (BUF[1]<<8)|BUF[0];
   mpu_value.Accel[0]/=164;                 //读取计算X轴数据
   Data_Buf[0] = mpu_value.Accel[0];

         BUF[2]=MPU9250_Read_Reg(ACCEL_YOUT_L);
   BUF[3]=MPU9250_Read_Reg(ACCEL_YOUT_H);
   mpu_value.Accel[1]=        (BUF[3]<<8)|BUF[2];
   mpu_value.Accel[1]/=164;                                                    //读取计算Y轴数据
         Data_Buf[1] = mpu_value.Accel[1];
       
   BUF[4]=MPU9250_Read_Reg(ACCEL_ZOUT_L);
   BUF[5]=MPU9250_Read_Reg(ACCEL_ZOUT_H);
   mpu_value.Accel[2]=  (BUF[5]<<8)|BUF[4];
   mpu_value.Accel[2]/=164;         //读取计算Z轴数据
         Data_Buf[2] = mpu_value.Accel[2];
}


/**********************陀螺仪读取*****************************-----修改*/
//void READ_MPU9250_GYRO(void)
//{

//   BUF[0]=MPU9250_Read_Reg(GYRO_XOUT_L);
//   BUF[1]=MPU9250_Read_Reg(GYRO_XOUT_H);
//   mpu_value.Gyro[0]=        (BUF[1]<<8)|BUF[0];
//   mpu_value.Gyro[0]/=16.4;                                                    //读取计算X轴数据

//   BUF[2]=MPU9250_Read_Reg(GYRO_YOUT_L);
//   BUF[3]=MPU9250_Read_Reg(GYRO_YOUT_H);
//   mpu_value.Gyro[1]=        (BUF[3]<<8)|BUF[2];
//   mpu_value.Gyro[1]/=16.4;                                                    //读取计算Y轴数据
//   BUF[4]=MPU9250_Read_Reg(GYRO_ZOUT_L);
//   BUF[5]=MPU9250_Read_Reg(GYRO_ZOUT_H);
//   mpu_value.Gyro[2]=        (BUF[5]<<8)|BUF[4];
//   mpu_value.Gyro[2]/=16.4;                                                //读取计算Z轴数据
//}



void  READ_MPU9250_GYRO(void)
{
   BUF[0]=MPU9250_Read_Reg(GYRO_XOUT_L);
   BUF[1]=MPU9250_Read_Reg(GYRO_XOUT_H);
   mpu_value.Gyro[0]=        (BUF[1]<<8)|BUF[0];
   mpu_value.Gyro[0]/=16.4;         //读取计算X轴数据
   Data_Buf[3]=mpu_value.Gyro[0];
       
   BUF[2]=MPU9250_Read_Reg(GYRO_YOUT_L);
   BUF[3]=MPU9250_Read_Reg(GYRO_YOUT_H);
   mpu_value.Gyro[1]=        (BUF[3]<<8)|BUF[2];
   mpu_value.Gyro[1]/=16.4;         //读取计算Y轴数据
         Data_Buf[4]=mpu_value.Gyro[1];
       
   BUF[4]=MPU9250_Read_Reg(GYRO_ZOUT_L);
   BUF[5]=MPU9250_Read_Reg(GYRO_ZOUT_H);
   mpu_value.Gyro[2]=        (BUF[5]<<8)|BUF[4];
   mpu_value.Gyro[2]/=16.4;                                                    //读取计算Z轴数据
         Data_Buf[5]=mpu_value.Gyro[2];

}



/**********************磁力计读取***************************/
//i2c_Mag_read(AK8963_ST2_REG) 此步读取不可省略
//数据读取结束寄存器,reading this register means data reading end
//AK8963_ST2_REG 同时具有数据非正常溢出检测功能
//详情参考 MPU9250 PDF
/**********************************************************/
//void READ_MPU9250_MAG(void)
void  READ_MPU9250_MAG(void)
{        
       
       
        u8 x_axis,y_axis,z_axis;
       
        x_axis=i2c_Mag_read(AK8963_ASAX);// X轴灵敏度调整值
        y_axis=i2c_Mag_read(AK8963_ASAY);
        z_axis=i2c_Mag_read(AK8963_ASAZ);
       
        if((i2c_Mag_read(AK8963_ST1_REG)&AK8963_ST1_DOR)==0)//data ready
        {
                        //读取计算X轴数据
                 BUF[0]=i2c_Mag_read(MAG_XOUT_L); //Low data       
                 if((i2c_Mag_read(AK8963_ST2_REG)&AK8963_ST2_HOFL)==1)// data reading end register & check Magnetic sensor overflow occurred
                 {
                         BUF[0]=i2c_Mag_read(MAG_XOUT_L);//reload data
                 }
                 BUF[1]=i2c_Mag_read(MAG_XOUT_H); //High data       
                 if((i2c_Mag_read(AK8963_ST2_REG)&AK8963_ST2_HOFL)==1)// data reading end register
                 {
                         BUF[1]=i2c_Mag_read(MAG_XOUT_H);
                 }
                 mpu_value.Mag[0]=((BUF[1]<<8)|BUF[0])*(((x_axis-128)>>8)+1);                //灵敏度纠正 公式见/RM-MPU-9250A-00 PDF/ 5.13       
           Data_Buf[6]=mpu_value.Mag[0];
                 
                //读取计算Y轴数据
                        BUF[2]=i2c_Mag_read(MAG_YOUT_L); //Low data       
                 if((i2c_Mag_read(AK8963_ST2_REG)&AK8963_ST2_HOFL)==1)// data reading end register
                 {
                         BUF[2]=i2c_Mag_read(MAG_YOUT_L);
                 }                 
                 BUF[3]=i2c_Mag_read(MAG_YOUT_H); //High data       
                 if((i2c_Mag_read(AK8963_ST2_REG)&AK8963_ST2_HOFL)==1)// data reading end register
                 {
                         BUF[3]=i2c_Mag_read(MAG_YOUT_H);
                 }
                  mpu_value.Mag[1]=((BUF[3]<<8)|BUF[2])*(((y_axis-128)>>8)+1);       
                Data_Buf[7]=mpu_value.Mag[1];
                 
                //读取计算Z轴数据
                 BUF[4]=i2c_Mag_read(MAG_ZOUT_L); //Low data       
                 if((i2c_Mag_read(AK8963_ST2_REG)&AK8963_ST2_HOFL)==1)// data reading end register
                 {
                         BUF[4]=i2c_Mag_read(MAG_ZOUT_L);
                 }         
                 BUF[5]=i2c_Mag_read(MAG_ZOUT_H); //High data       
                 if((i2c_Mag_read(AK8963_ST2_REG)&AK8963_ST2_HOFL)==1)// data reading end register
                 {
                         BUF[5]=i2c_Mag_read(MAG_ZOUT_H);
                 }
                  mpu_value.Mag[2]=((BUF[5]<<8)|BUF[4])*(((z_axis-128)>>8)+1);       
                 Data_Buf[8]=mpu_value.Mag[2];
        }               
       
       

       
}



[/mw_shl_code]





这是 main.c



[mw_shl_code=c,true]//#include "stm32f10x.h"



/* --------------接收MPU9250数据  通过蓝牙发送到串口  加入姿态解算 -------------*/

#include "stm32f10x.h"
#include "spi.h"
#include "delay.h"
#include "led.h"
#include "usart.h"
#include "stdio.h"
#include <math.h>
#include "MahonyAHRS.h"




extern  short Data_Buf[9];
     short Data_Buf_H[9];
extern  float Angle[3];                 

int main()
{
       
        u8 t;
  delay_init();
        uart_init(115200);
        LED_Init();
       
        spi_Init();
        Init_MPU9250();

       
        while(1)
        {
       
        READ_MPU9250_ACCEL();
        READ_MPU9250_GYRO();
        READ_MPU9250_MAG();

  Mahony_update((float)Data_Buf[3], (float)Data_Buf[4], (float)Data_Buf[5],(float)Data_Buf[0],(float)Data_Buf[1],(float)Data_Buf[2],(float)Data_Buf[6],(float)Data_Buf[7],(float)Data_Buf[8]);

        for (t=0;t<9;t++)
                {
                  USART_SendData(USART1,Data_Buf[t]);
                        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);//等待数据发送结束
                       
                        Data_Buf_H[t]=Data_Buf[t]>>8 & 0x00FF; //右移八位  并且
                        USART_SendData(USART1,Data_Buf_H[t]);
                  while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); //等待数据发送结束
                }
               
               
          GPIO_SetBits(GPIOA,GPIO_Pin_2);
  delay_ms(30);
       
        GPIO_ResetBits(GPIOA,GPIO_Pin_2);
                delay_ms(30);
       
//                delay_ms(10);


        }
       
}

[/mw_shl_code]


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
openhui
1楼-- · 2019-07-21 04:56
搞定了  mpu9250 虚焊 用力按着就有数了   之前有拿万用表测 引脚都是连着的啊
重新牢固焊了下
非常感谢大家
03零三邓何芯桃
2楼-- · 2019-07-21 09:24
帮你顶帖问问吧
openhui
3楼-- · 2019-07-21 14:36
03零三邓何芯桃 发表于 2019-4-2 13:29
帮你顶帖问问吧

非常 非常 感谢
CUIP904
4楼-- · 2019-07-21 20:18
请问有MiniSTM32开发板的MPU9250的程序吗。。。我手里有阿波罗开发板的,但是不知道怎么修改
openhui
5楼-- · 2019-07-22 00:19
 精彩回答 2  元偷偷看……

一周热门 更多>