at89c51cc01 发表于 2012-11-5 18:21:28

马潮老师书中的TWI程序问题疑惑

发现马老师书的TWI部分程序疑惑问题,比如在demo_16_4.c中
unsigned char I2C_write(unsigned char c)    //向总线写一字节,并返回有无应答
{
    unsigned char ack=1;
    TWDR = c;
    TWCR = (1<<TWINT)|(1<<TWEN);
    while (!(TWCR & (1<<TWINT))){};
    if((TWSR & 0xF8) != TW_MT_SLA_ACK)   
      ack = 0;
    return ack;
}

if((TWSR & 0xF8) != TW_MT_SLA_ACK)   // 这里是写地址或数据的函数,应该是判断TW_MT_DATA_ACK或TW_MT_DATA_NACK啊
请高手也分析一下,当然, 程序可以工作,比如对AT24C256读写一般是没问题的.

machao 发表于 2012-11-9 00:08:15

请参看表16-2中TWSR的值,当TWSR为0x18(即TW_MT_SLA_ACK) 时,表示数据已经发出并收到了从机的ACK信号。由于是用的I2C硬件接口,从机的ACK信号是I2C硬件电路自动检测的,并反映在TWSR寄存器中,程序只要判断TWSR的值就可以了。

at89c51cc01 发表于 2012-11-9 13:25:59

谢谢马老师!
书上说0x18的意思是:
SLA+W has been transmitted;
ACK has been received

at89c51cc01 发表于 2012-11-24 11:51:12

顶起,不知是不是这样

machao 发表于 2012-11-28 18:40:32

你可以仔细看书,p472的图16-6是最完整的过程。
在我的例子里,发送写地址和发送数据,都使用了检验TWSR==0x18,其实发送写地址和发送数据的操作方式相同的,只是TWSR不同。在我的代码中,进行了简化,在上层操作中并不判断ACK的标志是否对,所以可以正常使用。在一般系统中通常是这样使用的,没问题。

如果是要求非常高系统,I2C总线上有多个从器件,那么需要增加I2C_write_data()低层,同I2C_write()相同,只是判断TWSR==0X28。前一个写数据,后一个写地址。但上层使用这个函数后,就需要判断ACK,如果不对,出错处理。显然这样非常完整规范的代码编写更为复杂。
页: [1]
查看完整版本: 马潮老师书中的TWI程序问题疑惑