搜索
bottom↓
回复: 6

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

[复制链接]

出0入0汤圆

发表于 2014-11-22 13:44:26 | 显示全部楼层 |阅读模式
本帖最后由 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);
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2014-11-22 14:05:13 | 显示全部楼层
IIC上拉      

出0入0汤圆

 楼主| 发表于 2014-11-22 14:06:32 | 显示全部楼层

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

出0入0汤圆

发表于 2014-11-22 15:03:40 | 显示全部楼层
最好用逻缉分析仪看一下。很容易看出错误
没有的话,查一下以下:
1.检查slave地址
2.I2C上拉,4.7K 10K都行
3.delay

出0入0汤圆

 楼主| 发表于 2014-11-22 16:26:57 | 显示全部楼层
Puppey 发表于 2014-11-22 15:03
最好用逻缉分析仪看一下。很容易看出错误
没有的话,查一下以下:
1.检查slave地址

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

出0入0汤圆

发表于 2014-11-22 17:33:15 | 显示全部楼层
FreeStyler 发表于 2014-11-22 16:26
SLAVE地址是0XD0。。。请问一下上拉电阻的意义是什么?

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

出0入0汤圆

 楼主| 发表于 2014-11-22 18:34:15 | 显示全部楼层
Puppey 发表于 2014-11-22 17:33
通俗的讲,就是把总线电平拉高,为什么要拉高?自己去看I2C协议说明吧 ...

我试过了上拉4.7K电阻到3.3V电源和加长延时时间以后发现还是一直读出FF,说明6050还是没有产生ACK信号,程序的时序按照论坛的51测试程序修改的,应该只是延时有问题,请问这是怎么回事呢?是不是6050模块本身的问题?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 12:29

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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