刚开始调试TWI总线与AT24C02连接时,因为我是第1次以硬件的方式实现I2C,因此走了几天的弯路。今天完全调试通了。写些调试经验,省得以后有人继续走弯路。
可以这么说,利用Proteus调试I2C还是很方便的,比如在图纸上连接好MEGA8和AT24C02后,如果要看I2C调试情况,可以用两种方法:
第1种方法是在I2C总线上多连接一个I2C Debugger仪器,在仿真调试期中,该仪器可以显示I2C数据传送时间、S(START状态)、Sr(ReStart状态)、A(Ask响应)、N (No ask状态)、P(Stop状态)、数据(同时显示数据的16进制值和每位的值)。通过查看I2C Debugger窗口的显示,可以知道I2C总线上发送和接受的数据是否正确。
第2种方法是利用24C系列的I2C EEPROM元件属性设置中的Log功能。这些Log功能默认情况下是No,即不使用。我们可以把它设置成Yes。特别要提到的一点:这些Log功能的最后一项是Log to main Simulation Log,即是否将记录下来的情况写到主窗口仿真Log文件。如果要看到Log的情况,该选项必须选Yes,否则看不到历史记录。如果24C系列的元件接收或者发送标志信息和数据信息,在主窗口的Log文件中可以看到这些信息记录。具体看的方法是在System菜单中单击Text Viewer即可。
下面谈几点Proteus中24c系列元件的调试特点。
原理图中放好的24c系列元件的某地址一旦被正确写入数据,无论是否停止调试或者重新装入数据文件或者重新装入该原理图,该数据仍然保持。很神奇吧。我在Proteus 6.9sp4中发现了这个问题,这个情况和我们想象的情况完全不同。
另外,24c02元件的读写必须按照以下方法进行:
读。AVR必须先发送START位,然后检测总线是否在控制下,很多情况下,TWI_STATUS返回TW_START、TW_REP_START或者都可以继续传送。接下来传送【地址|TW_WRITE】,然后,检查TWI_STATUS,如果正确,应该返回TW_MT_SLA_ACK,然后就可以发送地址字节,如果发送成功,TWI_STATUS返回TW_MT_DATA_ACK,接下来就可以继续发送START位、【地址|TW_READ】,然后 AVR自动切换到主机读状态,等待一点时间后,如果读到东西,就可以在TWI_STATUS中检测到TW_MR_DATA_ACK或者 TW_MR_DATA_NACK,TWDR中得到的就是读出的数据。
值得注意的是,在Proteus仿真时,响应很慢,很多时候TWI_STATUS中得到是TW_NO_INFO(无信息),出现这种情况是因为AVR收到应答信号后,还需要等一点时间TWI_STATUS中的值才会更新。为了读到正确的数据,可以在TWINT置位后,等上了几十个微妙,然后就可以得到正确的TWI_STATUS的值了。
究其原因,我估计是当数据发送出去或者接受完毕后,TWINT就置位了,但是ACK/NACK还需要一点时间才能收到,这样就差了一点时间才能收到正确的 TWI_STATUS的值。这个问题搞了我很久,也和想象中的不一样,而且MEGA8的手册中也没有提到这个事,最后搞了好久,脑袋突然灵光起来才试出来的。
写下此文,与君共勉。