EEPROM M24C64替换AT24C64出现读取数据为0xff情况解决办法
硬件情况
STM32F103CBT6+模拟IIC,主频72MHz,IIC上拉电阻3.3kΩ
出现原因
- 在IIC停止信号上,SCL、SDA翻转间隔不足以被M24C64识别,导致读写出错。
修改前IIC停止代码如下:
c
void I2C_Stop(void)
{
I2C_SCL_LOW();
I2C_SDA_LOW(); // STOP:when CLK is high DATA change form low to high
Delay_us(1);
I2C_SCL_HIGH();
I2C_SDA_HIGH(); // 发送I2C总线结束信号
Delay_us(1);
}
- 使用NOP指令测试M24C64能识别的最小翻转间隔代码如下:
c
void I2C_Stop(void)
{
I2C_SCL_LOW();
I2C_SDA_LOW(); // STOP:when CLK is high DATA change form low to high
Delay_us(1);
I2C_SCL_HIGH();
__asm__ volatile("NOP");
__asm__ volatile("NOP");
__asm__ volatile("NOP");
__asm__ volatile("NOP");
__asm__ volatile("NOP");
__asm__ volatile("NOP");
I2C_SDA_HIGH(); // 发送I2C总线结束信号
Delay_us(1);
}
测试
-
在72MHz频率下,使用400MHz采样率的逻辑分析仪测得加NOP延时前翻转延时为57.5ns,无法被M24C64识别。
-
其余条件不变情况下,增加6条NOP指令后,翻转延时为142.5ns,M24C64可以识别,读写正常。
-
六条指令周期时长约 6 * 1 / 72000000 * 10^9=83.33ns约等于142.5-7.5=85ns
结论
- 为了兼容多种IIC设备,在使用模拟IIC程序时,IIC停止等信号SDA、SCL间翻转应加适当延时,避免无法识别的情况。
- 在此情况下应确保翻转延时大于142.5ns的极限延时,实际使用中应留有余量,可使用1us等常见延时。
c
void I2C_Stop(void)
{
I2C_SCL_LOW();
I2C_SDA_LOW(); // STOP:when CLK is high DATA change form low to high
Delay_us(1);
I2C_SCL_HIGH();
Delay_us(1);//翻转延时,确保IIC设备能识别
I2C_SDA_HIGH(); // 发送I2C总线结束信号
Delay_us(1);
}