|
TWI的STOP信号的疑问
向各位请教TWI的STOP信号在什么条件下才能产生?
这段程序在通信失败的条件下重复通信r次
while( I2C_Write_(wrDAdr,wordAdr,pWrDat,num)==I2C_ERR && r>0)
{
if( !(TWCR&(1<<TWINT)) ) TWCR=(1<<TWINT); //保证发出stop信号前TWINT置1
I2CStop();r--;} //#define I2CStop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
在示波器下观察当提供错误地址,进入重复通信时大括号中的stop信号并没有发出,这导致了在重复通信
中的start信号都变成了restart信号,其影响了对TWSR中的值的判断,使得之后的重复通信都失败了。
但是当只进行一次写入操作且操作成功时(单独一次写入,后面没有其他写入程序)却又能够观察到
stop信号。
就此推理TWI好像是这样的
程序这样执行 :start->地址->数据->stop ->start->地址->数据->stop ->start->地址->数据->stop......
中间的stop信号都没有了,只有最后一个stop信号会产生,中间的start信号都变成了restart信号
stop好像只有在特定情况下才会发出,比如:没有start信号时stop信号不会发出,报文为空时stop信号不
会发出,stop信号后面紧接着start信号时stop信号不会发出...
感觉很迷惑,请高手指教。
以下是I2C_Write_()函数
bool I2C_Write_(INT16U wrDAdr,INT8U wordAdr,
INT8U *pWrDat,INT8U num)
{
INT8U i;
if( I2C_Start()==I2C_ERR )
return I2C_ERR;
if( I2C_SendWrDAdr_((wrDAdr&0xfffe)|I2C_WRITE)==I2C_ERR )//保证写控制位正确
return I2C_ERR;
if( I2C_SendDat(wordAdr)==I2C_ERR ) //从地址当作一般数据发送
return I2C_ERR;
for(i=0;i<num;i++)
if( I2C_SendDat(*(pWrDat++))==I2C_ERR )
return I2C_ERR;
I2CStop();
return I2C_CRR;
}
以下是senddat函数
bool I2C_SendDat(INT8U configDat)
{
I2CSendByte(configDat);
I2CWaitAck();
if( I2CChkAck()!=I2C_MT_DATA_ACK )
return I2C_ERR;
return I2C_CRR;
}
以下是SendRdDAdr_函数
bool I2C_SendRdDAdr_(INT8U rdDAdr)
{
if( rdDAdr&0xF000 == 0xF000 ) //判断是否为 10位 器件地址
if( I2C_SendWrDAdr( (INT8U)rdDAdr>>8 )==I2C_ERR ) //设置 (高位)器件读地址
return I2C_ERR;
if( I2C_SendWrDAdr( (INT8U)rdDAdr )==I2C_ERR ) //设置 (低位)器件读地址
return I2C_ERR;
return I2C_CRR;
}
以下是宏定义
#define I2CStart() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
#define I2CStop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
I2CWaitAck() {while(!(TWCR&(1<<TWINT)));}
I2CChkAck() (TWSR&0xf8)
I2CSendByte(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|