高级会员

- 积分
- 764
- 金钱
- 764
- 注册时间
- 2015-11-28
- 在线时间
- 208 小时
|

楼主 |
发表于 2016-4-25 18:45:55
|
显示全部楼层
从上图可以看出应答和非应答的时序;
应答和非应答是由我们的主机发送的,而且是在接收完一个字节发送的。我们接收字节的时候会把 CT_SDA_IN();也就是说会把SDA线设置为输入状态这个时候IO口是高阻状态的,从外面看上去是逻辑1. 我们的时序要求在接收到一个字节后就立马发送应答信号。 由于之前我们的IO是配置为读取状态是高阻状态也就是逻辑1 我们读取的代码是这么写的,读完过后SCL=1; SDA=1;(这里SDA我不清楚是不是1了,只是猜测我脑袋有限只能想到这个解释办法)[mw_shl_code=c,true]
u8 CT_IIC_Read_Byte(unsigned char ack)
{
u8 i,receive=0;
CT_SDA_IN();//SDA设置为输入
delay_us(4);
for(i=0;i<8;i++ )
{
CT_IIC_SCL=0;
CT_Delay();
CT_IIC_SCL=1;
receive<<=1;
if(CT_READ_SDA)receive++;
//receive|=CT_READ_SDA;
}
if (!ack)CT_IIC_NAck();//发送nACK
else CT_IIC_Ack(); //发送ACK
return receive;
}[/mw_shl_code]
)如果是这样的话那么这就是一个非应答信号了。只能收到头1个字节就非应答了。事实上串口也只输出了头一个正确的字节。
[mw_shl_code=c,true]
//产生ACK应答
void CT_IIC_Ack(void)
{
CT_SDA_OUT();
CT_IIC_SCL=0;
CT_Delay();
CT_IIC_SDA=0;
CT_Delay();
CT_IIC_SCL=1;
CT_Delay();
CT_IIC_SCL=0;
}[/mw_shl_code]
。一个非应答的信号需要4US,上面的CT_SDA_OUT();可能就4US了。造成了非应答。
[mw_shl_code=c,true]
//产生ACK应答
void CT_IIC_Ack(void)
{
CT_IIC_SCL=0;
CT_SDA_OUT();
CT_Delay();
CT_IIC_SDA=0;
CT_Delay(); //延迟4US
CT_IIC_SCL=1;
CT_Delay();
CT_IIC_SCL=0;
}[/mw_shl_code]
如果在CT_SDA_OUT();前把SCL拉低就不会造成非应答,非应答是指SCL为高的时候SDA有4US的高电平。
这个时候把SDA配置为输出,SDA拉低过后延迟4US拉高SCL延迟4US(在SCL为高的时候有4us的低电平)形成了应答信号。 这个时候时序才正确程序才能正常进行。
当然以上的推断仅仅是在IO口配置成输入,IO口会呈现高阻状态而且IIC通信器件会把这个状态当成是逻辑1以上推论才正确。 如果哪位大神觉得我这错得像耍猴一样,请不要吝啬您的教诲!请帮我指出错误。谢谢!
|
|