新人求助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);
}
IIC上拉 huangyiting1990 发表于 2014-11-22 14:05
IIC上拉
把模拟的I2C GPIO上拉到电源么?上拉电阻选10K或者4.7K? 最好用逻缉分析仪看一下。很容易看出错误
没有的话,查一下以下:
1.检查slave地址
2.I2C上拉,4.7K 10K都行
3.delay Puppey 发表于 2014-11-22 15:03
最好用逻缉分析仪看一下。很容易看出错误
没有的话,查一下以下:
1.检查slave地址
SLAVE地址是0XD0。。。请问一下上拉电阻的意义是什么? FreeStyler 发表于 2014-11-22 16:26
SLAVE地址是0XD0。。。请问一下上拉电阻的意义是什么?
{:smile:} 通俗的讲,就是把总线电平拉高,为什么要拉高?自己去看I2C协议说明吧 Puppey 发表于 2014-11-22 17:33
通俗的讲,就是把总线电平拉高,为什么要拉高?自己去看I2C协议说明吧 ...
我试过了上拉4.7K电阻到3.3V电源和加长延时时间以后发现还是一直读出FF,说明6050还是没有产生ACK信号,程序的时序按照论坛的51测试程序修改的,应该只是延时有问题,请问这是怎么回事呢?是不是6050模块本身的问题?
页:
[1]