I2C eeprom调试经验

在写本文之前我不得不痛批ST的comtex-M3的I2C做得实在是太烂了!就这样一个简简单单的I2C,需要无数多的配置,无数多的寄存器,无数多的标志位,难道ST的目标就是把简单的东西复杂化么?复杂了就难用。另一方面,ST官方给的I2C eeprom例程中while死等的语句比比皆是,本来I2C就做得复杂,还四处布满死等代码,很容易在使用中让系统死机。

言归正传,前边的抱怨也是我调试I2C的起因。查过很多资料,普遍对于STM32I2C的在产品(不是实验室)中的使用表示需要谨慎,陷阱很多,bug很多。前前后后折磨了我估计有一个月吧,心里始终觉得官方的东西应该还是要好点,所以一直将就官方的代码在用,直到我的系统莫名奇妙的死机,究其原因是I2C操作引起为止,终于下定决心还是用模拟I2C。

目标平台是STM32C8T6+atmel的eeprom,通信总线为串行I2C总线。

调试过程遇到的问题:
1.字节写操作正常,但是字节读函数出错
原因:一厢情愿的认为写eeprom是在七位器件地址后添加写标志,则读eeprom也应该在七位期间地址后添加读标志,而事实上读eeprom也是在七位地址后添加写标志。

2.断续单字节读写正常,但是采用连续的单字节读写出错。
原因:eeprom写过程的结束并不是I2C总线写结束就结束,实际上I2C总线的写入数据先被保存到了eeprom内部的缓冲区,当遇到I2C结束条件后,eeprom才启动内部写过程,这个过程才是保存数据的过程。非常悲哀的是这个过程比较长,官方文档标注为5ms。如果在这5ms以内对eeprom芯片访问将被忽略。

3.查询eeprom写过程是否结束造成死机
官方文档说eeprom内部写周期最长为5ms,在很多情况下是远远低于5ms的,为了节约时间,官方给出一个解决办法。当写周期完毕后就开始进行应答查询,来确定eeprom写周期何时结束。所谓应答查询官方解释为:就是向eeprom发送一个I2C起始条件后发送器件地址和一个读写标志位,当eeprom完成内部写周期会回应一个ACK,这时MCU就可以进行正常的其他读写过程了。官方原文如下:
杯具就是始于我画红线的那句话,它说可以在器件地址后任意填写读写标志。我就填了读标志, 事实证明在eeprom写入过程采用读查询将导致系统死机,I2C总线不能被正常拉高,可能是eeprom内部已经把总线拉到了地!不管怎样,反正就是死机了。经过多次尝试最终发现应答查询只能采用写应答查询可以正常确定eeprom内部写周期的结束。

原因:运气太背了!

总结:对于前两个问题归结为自己看资料太不细致,没有认真看先关参数。对于第二个问题,只能说我必须得怪ATMEL! 

调试过程借鉴了"梅川酷子"的I2C代码,在此表示感谢!原文地址: http://blog.ednchina.com/kuge/1969761/message.aspx

你可能感兴趣的:(调试记录)