jib943 发表于 2013-8-10 11:22:11

求救!!MPU6050能读出who am i但是读加速度和陀螺仪都是0

求救!!MPU6050能读出who am i但是读加速度和陀螺仪都是0。读WHO_AM_I读到0x68.有点迷茫了#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
#include "mpu6050.h"
#include "i2c.h"


#define   uchar unsigned char
#define   uint unsigned int       

//定义MPU6050内部地址********************
#define        SMPLRT_DIV                0x19        //陀螺仪采样率,典型值:0x07(125Hz)
#define        CONFIG                        0x1A        //低通滤波频率,典型值:0x06(5Hz)
#define        GYRO_CONFIG                0x1B        //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define        ACCEL_CONFIG        0x1C        //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
#define        ACCEL_XOUT_H        0x3B
#define        ACCEL_XOUT_L        0x3C
#define        ACCEL_YOUT_H        0x3D
#define        ACCEL_YOUT_L        0x3E
#define        ACCEL_ZOUT_H        0x3F
#define        ACCEL_ZOUT_L        0x40
#define        TEMP_OUT_H                0x41
#define        TEMP_OUT_L                0x42

#define        GYRO_XOUT_H                0x43
#define        GYRO_XOUT_L                0x44       
#define        GYRO_YOUT_H                0x45
#define        GYRO_YOUT_L                0x46
#define        GYRO_ZOUT_H                0x47
#define        GYRO_ZOUT_L                0x48

#define        PWR_MGMT_1                0x6B        //电源管理,典型值:0x00(正常启用)
#define        WHO_AM_I                0x75        //IIC地址寄存器(默认数值0x68,只读)
//****************************

#define        MPU6050_Addr   0xD0          //定义器件在IIC总线中的从地址,根据ALTADDRESS地址引脚不同修改

unsigned char TX_DATA;       //显示据缓存区
unsigned char BUF;       //接收数据缓存区
chartest=0;                                //IIC用到
short T_X,T_Y,T_Z,T_T;               //X,Y,Z轴,温度

//************************************
/*模拟IIC端口输出输入定义*/
#define SCL_H         GPIOB->BSRR = GPIO_Pin_6
#define SCL_L         GPIOB->BRR= GPIO_Pin_6
   
#define SDA_H         GPIOB->BSRR = GPIO_Pin_7
#define SDA_L         GPIOB->BRR= GPIO_Pin_7

#define SCL_read      GPIOB->IDR& GPIO_Pin_6
#define SDA_read      GPIOB->IDR& GPIO_Pin_7





//void Delay(__IO u32 nCount);

/*
* 函数名:main
* 描述:主函数
* 输入:无
* 输出:无
*/

/*******************************************************************************
* Function Name: I2C_GPIO_Config
* Description    : Configration Simulation IIC GPIO
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_GPIO_Config(void)
{
GPIO_InitTypeDefGPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin =GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name: I2C_delay
* Description    : Simulation IIC Timing series delay
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_delay(void)
{
               
   u8 i=30; //这里可以优化速度        ,经测试最低到5还能写入
   while(i)
   {
   i--;
   }
}

void delay5ms(void)
{
               
   int i=5000;
   while(i)
   {
   i--;
   }
}
/*******************************************************************************
* Function Name: I2C_Start
* Description    : Master Start Simulation IIC Communication
* Input          : None
* Output         : None
* Return         : Wheather       Start
****************************************************************************** */
bool I2C_Start(void)
{
        SDA_H;
        SCL_H;
        I2C_delay();
        if(!SDA_read)return FALSE;        //SDA线为低电平则总线忙,退出
        SDA_L;
        I2C_delay();
        if(SDA_read) return FALSE;        //SDA线为高电平则总线出错,退出
        SDA_L;
        I2C_delay();
        return TRUE;
}
/*******************************************************************************
* Function Name: I2C_Stop
* Description    : Master Stop Simulation IIC Communication
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_Stop(void)
{
        SCL_L;
        I2C_delay();
        SDA_L;
        I2C_delay();
        SCL_H;
        I2C_delay();
        SDA_H;
        I2C_delay();
}
/*******************************************************************************
* Function Name: I2C_Ack
* Description    : Master Send Acknowledge Single
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_Ack(void)
{       
        SCL_L;
        I2C_delay();
        SDA_L;
        I2C_delay();
        SCL_H;
        I2C_delay();
        SCL_L;
        I2C_delay();
}   
/*******************************************************************************
* Function Name: I2C_NoAck
* Description    : Master Send No Acknowledge Single
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_NoAck(void)
{       
        SCL_L;
        I2C_delay();
        SDA_H;
        I2C_delay();
        SCL_H;
        I2C_delay();
        SCL_L;
        I2C_delay();
}
/*******************************************************************************
* Function Name: I2C_WaitAck
* Description    : Master Reserive Slave Acknowledge Single
* Input          : None
* Output         : None
* Return         : Wheather       Reserive Slave Acknowledge Single
****************************************************************************** */
bool I2C_WaitAck(void)        //返回为:=1有ACK,=0无ACK
{
        SCL_L;
        I2C_delay();
        SDA_H;                       
        I2C_delay();
        SCL_H;
        I2C_delay();
        if(SDA_read)
        {
      SCL_L;
          I2C_delay();
      return FALSE;
        }
        SCL_L;
        I2C_delay();
        return TRUE;
}
/*******************************************************************************
* Function Name: I2C_SendByte
* Description    : Master Send a Byte to Slave
* Input          : Will Send Date
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_SendByte(u8 SendByte) //数据从高位到低位//
{
    u8 i=8;
    while(i--)
    {
      SCL_L;
      I2C_delay();
      if(SendByte&0x80)
      SDA_H;
      else
      SDA_L;   
      SendByte<<=1;
      I2C_delay();
                SCL_H;
      I2C_delay();
    }
    SCL_L;
}
/*******************************************************************************
* Function Name: I2C_RadeByte
* Description    : Master Reserive a Byte From Slave
* Input          : None
* Output         : None
* Return         : Date From Slave
****************************************************************************** */
unsigned char I2C_RadeByte(void)//数据从高位到低位//
{
    u8 i=8;
    u8 ReceiveByte=0;

    SDA_H;                               
    while(i--)
    {
      ReceiveByte<<=1;      
      SCL_L;
      I2C_delay();
          SCL_H;
      I2C_delay();       
      if(SDA_read)
      {
      ReceiveByte|=0x01;
      }
    }
    SCL_L;
    return ReceiveByte;
}
//ZRX         
//单字节写入*******************************************

bool Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data)                     //void
{
        if(!I2C_Start())return FALSE;
    I2C_SendByte(SlaveAddress);   //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址
    if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}
    I2C_SendByte(REG_Address );   //设置低起始地址      
    I2C_WaitAck();       
    I2C_SendByte(REG_data);
    I2C_WaitAck();   
    I2C_Stop();
    delay5ms();
    return TRUE;
}

//单字节读取*****************************************
unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address)
{   unsigned char REG_data;          
        if(!I2C_Start())return FALSE;
    I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址
    if(!I2C_WaitAck()){I2C_Stop();test=1; return FALSE;}
    I2C_SendByte((u8) REG_Address);   //设置低起始地址      
    I2C_WaitAck();
    I2C_Start();
    I2C_SendByte(SlaveAddress+1);
    I2C_WaitAck();

        REG_data= I2C_RadeByte();
    I2C_NoAck();
    I2C_Stop();
    //return TRUE;
        return REG_data;

}                                                     
//初始化MPU3050,根据需要请参考pdf进行修改************************
void Init_MPU6050(void)
{
        Single_Write(MPU6050_Addr,PWR_MGMT_1, 0x00);        //解除休眠状态
        Single_Write(MPU6050_Addr,SMPLRT_DIV, 0x07);
        Single_Write(MPU6050_Addr,CONFIG, 0x06);
        Single_Write(MPU6050_Addr,GYRO_CONFIG, 0x18);
        Single_Write(MPU6050_Addr,ACCEL_CONFIG, 0x01);
}
//******读取MPU6050数据****************************************
void READ_MPU6050(void)
{
BUF=Single_Read(MPU6050_Addr,GYRO_XOUT_L);
       
   BUF=Single_Read(MPU6050_Addr,GYRO_XOUT_H);
   T_X=        (BUF<<8)|BUF;
   T_X/=16.4;                                                    //读取计算X轴数据

       
       
       BUF=Single_Read(MPU6050_Addr,GYRO_YOUT_L);
   BUF=Single_Read(MPU6050_Addr,GYRO_YOUT_H);
   T_Y=        (BUF<<8)|BUF;
   T_Y/=16.4;                                                    //读取计算Y轴数据
   BUF=Single_Read(MPU6050_Addr,GYRO_ZOUT_L);
   BUF=Single_Read(MPU6050_Addr,GYRO_ZOUT_H);
   T_Z=        (BUF<<8)|BUF;
   T_Z/=16.4;                                              //读取计算Z轴数据

// BUF=Single_Read(MPU6050_Addr,TEMP_OUT_L);
// BUF=Single_Read(MPU6050_Addr,TEMP_OUT_H);
// T_T=(BUF<<8)|BUF;
// T_T = 35+ ((double) (T_T + 13200)) / 280;// 读取计算出温度
}
/*
********************************************************************************
** 函数名称 : Delay(vu32 nCount)
** 函数功能 : 延时函数
** 输    入        : 无
** 输    出        : 无
** 返    回        : 无
********************************************************************************
*/
void Delay(vu32 nCount)
{
for(; nCount != 0; nCount--);
}

/*
********************************************************************************
** 函数名称 : void Delayms(vu32 m)
** 函数功能 : 长延时函数       m=1,延时1ms
** 输    入        : 无
** 输    出        : 无
** 返    回        : 无
********************************************************************************
*/
void Delayms(vu32 m)
{
u32 i;

for(; m != 0; m--)       
       for (i=0; i<50000; i++);
}


int main(void)
{
        /* 配置系统时钟为72M */      
SystemInit();       
       
        /* LED 端口初始化 */
        LED_GPIO_Config();
        USART_Configuration();
        USART_Test();
        I2C_GPIO_Config();               //配置IIC使用端口
Delayms(10);                               //延时
Init_MPU6050();                     //初始化MPU3050
while (1)
{
                LED1( ON );                          // 亮
                Delay(0x6FFFEF);
                LED1( OFF );                  // 灭

                LED2( ON );
                Delay(0x6FFFEF);
                LED2( OFF );

                LED3( ON );
                Delay(0x6FFFEF);
                LED3( OFF );   
               
        //USART_SendData(USART1,Single_Read(MPU6050_Addr,0x75));
        USART_SendData(USART1,Single_Read(MPU6050_Addr,TEMP_OUT_H));
        USART_SendData(USART1,Single_Read(MPU6050_Addr,TEMP_OUT_L));        
        //        READ_MPU6050();                 //读取MPU3050数据
        /*        printf("X:%d\r\n",T_X);//转换X轴数据到数组
                printf("Y:%d\r\n",T_Y);;//转换Y轴数据到数组
                printf("Z:%d\r\n",T_Z);;//转换Z轴数据到数组
                printf("T:%d\r\n",T_T);//转换温度数据到数组
        */
}
}

jib943 发表于 2013-8-10 11:35:00

读控制寄存器的值都是正确的,就是我设置的值。但是读加速度计陀螺仪的寄存器就是读不到值!{:mad:}{:mad:}{:mad:}{:mad:}

woshisangao 发表于 2013-8-12 16:05:07

一上来就看见这么多代码,大家的热心锐减

jib943 发表于 2013-8-13 07:22:27

问题解决了。是模块有个悬空引脚和一个有用的脚连在一起。焊开就好了

ycysky 发表于 2013-10-15 11:50:17

楼主,你的哪两个脚焊到一起了会有这种情况,我的现在总是有一个轴Y周的加速度值一直读到为0不变,其他5个值都是对的,请问是何原因,换了好几个模块都是这样的。

jib943 发表于 2013-10-15 23:45:19

ycysky 发表于 2013-10-15 11:50 static/image/common/back.gif
楼主,你的哪两个脚焊到一起了会有这种情况,我的现在总是有一个轴Y周的加速度值一直读到为0不变,其他5个 ...

没印象了,是没有接进电路的两个脚。重新补焊一下焊开就好了

firstzys 发表于 2014-1-14 15:54:53

如果软件找不到问题,硬件原理没问题,那就真是焊接问题了{:hug:}
页: [1]
查看完整版本: 求救!!MPU6050能读出who am i但是读加速度和陀螺仪都是0