软件I2C读写24cl64异常 可读不可写
//产生IIC停止信号
void IIC_Stop(void)
{
// SDA_OUT();//sda线输出
// IIC_SCL=0;
// IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
// delay_us(4);
// IIC_SCL=1;
// IIC_SDA=1;//发送I2C总线结束信号
// delay_us(4);
SDA_OUT();//sda线输出
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
IIC_SCL=1;
delay_us(4);
IIC_SDA=1;//发送I2C总线结束信号
delay_us(4);
}
在正点原子软件模拟IIC例程更改,MCU:GD32F303RCT6,EEPROM:FM24C64D
下文为引用
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,过量耗电的情况消失。
这个就是单片机的推挽输出的特性了。
————————————————
版权声明:本文为CSDN博主「三日凌空」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42182035/article/details/115950441