3月末在调试一个eeprom芯片24lc64,我们要用软件模拟I2C控制它,但遇到了奇特的现象。
用我们之前写的I2C驱动去控制它时,不可写入,但是可以读取。
为了控制它,我们用硬件I2C去对它进行操作,可读写,证明芯片没有坏。经过示波器的帮助,发现它在写入的时序中有ack,但最后总是存不进去数据。
在与公司内的一位大佬长时间的共同调试后,发现问题在写时序的最后:
发出停止信号需要拉高时钟线再给数据线一个上升沿。我们的程序也是这么写的,但是,
拉高时钟线和拉低数据线的先后顺序影响了24lc64的判断,让它以为出现了一个起始信号(拉高时钟线后给数据线一个下降沿)
SDA_OUT;
SCL_H;//被误认为是起始信号
SDA_L;//后面的是停止信号
Delay();
SDA_H;
Delay();
解决办法也很简单,把上面的第二行和第三行调换一下位置就行了
SDA_OUT;
SDA_L;
SCL_H;
Delay();
SDA_H;
Delay();
对此我只能表示 ○( \\ 皿 // )っ…
毕竟原来的I2C驱动用了好几年了,只在这个芯片上出现了问题。
另外在调试过程中有了一个意外发现,若是把I2C引脚的输出方式改为推挽输出,那么24lc64给你的回复的高电平将变为2.5V,每次写操作结束它都会保持数据线在2.5V的状态约3.5ms,大概是在保存数据吧。整个过程中耗电量增加。
把引脚的输出方式改为开漏输出后,24lc64的回复高电平变为正常的3.3V,过量耗电的情况消失。
这个就是单片机的推挽输出的特性了。