大家好,情况是这样的:
今天我自己写了一遍MPU6050的IIC时序, 写完后发现调不通, 调试了一番后发现是void IIC_Ack(void);和void IIC_NAck(void);这两个函数出了问题。函数原型是
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
这样。 而
我把第一句和第二句位置写反了,是写成了
void IIC_Ack(void)
{
SDA_OUT();
IIC_SCL=0;
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
IIC_NAck()函数也是这样的错误,然后我不明白这两句的前后位置为什么有影响。 然后我猜想是不是
第二句IIC_SCL=0;和第三句IIC_SDA=0;之间需要一点延时,然后测试发现不是这样。
然后我又想到是不是因为 在SCL高电平下SDA不可以变化,在执行这个应答函数之前SDA线是输入状态,而在SCL是高电平情况下把SDA设置为输出,因为ODR寄存器有值所以改变了SDA线的电平造成的。 然后我想测试这一点,发现void IIC_Send_Byte(u8 txd);和u8 IIC_Read_Byte(unsigned char ack);这两个函数中也有设置SDA线输入,输出状态的语句,贴出函数原型:
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
//IIC_SDA=(txd&0x80)>>7;
if((txd&0x80)>>7)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;
delay_us(2); //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}
我发现这两个函数设置SDA输入,输出状态语句之前没有加IIC_SCL=0; 于是我在这两个函数中的SDA_OUT();和SDA_IN(); 语句之前分别加了IIC_SCL=0; delay_us(2); 发现在SDA_OUT();之前加没问题,在SDA_IN(); 前加就出问题了。所以我认为我这个想法也不对。
现在想不出来原因了,于是来论坛发帖问问大家,求大家帮帮忙,感谢
我的问题: 为什么应答与非应答函数中 第一句和第二句位置不能调换?
感谢回答!
一周热门 更多>