FreeStyler 发表于 2014-11-22 13:44:26

新人求助MPU6050读取WHO AM I 的问题

本帖最后由 FreeStyler 于 2014-11-22 13:46 编辑

第一次学做四轴,用的新唐的M0516单片机,软件模拟I2C,读MPU6050的WHO AM I 寄存器用串口发送得到的数据总是00,感觉是MPU6050一直没有给主机ACK信号引起的问题,请问应该怎么解决?以下是程序代码,请大家多多指教!
void I2C_delay(void)
{
   unsigned int i=5000;
   while(i!=0)
   {
                        i--;
   }
}
void delay5ms(void)
{
               
   int i=5000;
   while(i!=0)
   {
   i--;
   }
}


void I2C_Start(void)
{
                SDA=1;
                I2C_delay();
                SCL=1;
                I2C_delay();
                SDA=0;
                I2C_delay();
                SCL=0;
                I2C_delay();
}


void I2C_Stop(void)
{
    SCL=0;
                I2C_delay();
                SDA = 0;                  
                I2C_delay();
    SCL = 1;                         
    I2C_delay();               
    SDA = 1;                         
    I2C_delay();            
}


void I2C_Ack(void)
{       
                SCL=0;
                I2C_delay();
                SDA=0;
                I2C_delay();
                SCL=1;
                I2C_delay();
                SCL=0;
                I2C_delay();
}   


void I2C_NoAck(void)
{       
                SCL=0;
                I2C_delay();
                SDA=1;
                I2C_delay();
                SCL=1;
                I2C_delay();
                SCL=0;
                I2C_delay();
}


unsigned char I2C_WaitAck(void)        
{
                unsigned char errtime=0;
                SDA=1;                       
                I2C_delay();
                SCL=1;
                I2C_delay();
                while(SDA==1)
                {
                        errtime++;
                        if(errtime>250)
                        {
                                I2C_Stop();
                                return 0;
                        }
                }
                SCL=0;
                I2C_delay();
                return 1;
}


void I2C_SendByte(unsigned char SendByte)
{
                unsigned char i;
                SCL=0;
                for(i=0;i<8;i++)
               {
                                if(SendByte & (0x80)==1)
                                        SDA=1;
                                else
                                        SDA=0;   
      SendByte<<=1;
      I2C_delay();
                                SCL=1;
      I2C_delay();
                                SCL=0;
      I2C_delay();
    }
}


unsigned char I2C_ReadByte(void)
{
    unsigned char i;
    unsigned char ReceiveByte=0;
    SDA=1;                               
    for(i=0;i<8;i++)
    {
                        ReceiveByte<<=1;
                        SCL=0;
      I2C_delay();             
                        SCL=1;
      I2C_delay();       
      if(SDA==1)
      {
      ReceiveByte|=0x01;
      }
                        SCL=0;
                        I2C_delay();
    }
    return ReceiveByte;
}


unsigned char Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data)       
{
    I2C_Start();
    I2C_SendByte(SlaveAddress)
    if(I2C_WaitAck()==0)
                {
                        I2C_Stop();
                        return 0;
                }
    I2C_SendByte(REG_Address);
    I2C_WaitAck();       
    I2C_SendByte(REG_data);
    I2C_WaitAck();   
    I2C_Stop();
    delay5ms();
    return 1;
}


unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address)
{   
                unsigned char REG_data;          
                I2C_Start();
                I2C_SendByte(SlaveAddress)
                I2C_WaitAck();
                if(I2C_WaitAck()==0)
                {
                        I2C_Stop();
                        test=1;
                        return 0;
                }
    I2C_SendByte(REG_Address);   
    I2C_WaitAck();
    I2C_Start();
    I2C_SendByte(SlaveAddress+1);
    I2C_WaitAck();
                REG_data= I2C_ReadByte();
    I2C_NoAck();
    I2C_Stop();
                return REG_data;
}


void Init_MPU6050(void)
{
                Single_Write(MPU6050_Addr,PWR_MGMT_1, 0x80);        
                delay5ms();
                delay5ms();
                delay5ms();
                delay5ms();
                delay5ms();
                Single_Write(MPU6050_Addr,PWR_MGMT_1, 0x00);       
                delay5ms();
                delay5ms();
                delay5ms();

                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);
}

huangyiting1990 发表于 2014-11-22 14:05:13

IIC上拉      

FreeStyler 发表于 2014-11-22 14:06:32

huangyiting1990 发表于 2014-11-22 14:05
IIC上拉

把模拟的I2C GPIO上拉到电源么?上拉电阻选10K或者4.7K?

Puppey 发表于 2014-11-22 15:03:40

最好用逻缉分析仪看一下。很容易看出错误
没有的话,查一下以下:
1.检查slave地址
2.I2C上拉,4.7K 10K都行
3.delay

FreeStyler 发表于 2014-11-22 16:26:57

Puppey 发表于 2014-11-22 15:03
最好用逻缉分析仪看一下。很容易看出错误
没有的话,查一下以下:
1.检查slave地址


SLAVE地址是0XD0。。。请问一下上拉电阻的意义是什么?

Puppey 发表于 2014-11-22 17:33:15

FreeStyler 发表于 2014-11-22 16:26
SLAVE地址是0XD0。。。请问一下上拉电阻的意义是什么?

{:smile:}   通俗的讲,就是把总线电平拉高,为什么要拉高?自己去看I2C协议说明吧

FreeStyler 发表于 2014-11-22 18:34:15

Puppey 发表于 2014-11-22 17:33
通俗的讲,就是把总线电平拉高,为什么要拉高?自己去看I2C协议说明吧 ...

我试过了上拉4.7K电阻到3.3V电源和加长延时时间以后发现还是一直读出FF,说明6050还是没有产生ACK信号,程序的时序按照论坛的51测试程序修改的,应该只是延时有问题,请问这是怎么回事呢?是不是6050模块本身的问题?
页: [1]
查看完整版本: 新人求助MPU6050读取WHO AM I 的问题