EEPROM M24C64替换AT24C64出现读取数据为0xff情况解决办法

硬件情况

STM32F103CBT6+模拟IIC,主频72MHz,IIC上拉电阻3.3kΩ

 

出现原因

  • 在IIC停止信号上,SCL、SDA翻转间隔不足以被M24C64识别,导致读写出错。
    修改前IIC停止代码如下:
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能识别的最小翻转间隔代码如下:
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识别。
    image

  • 其余条件不变情况下,增加6条NOP指令后,翻转延时为142.5ns,M24C64可以识别,读写正常。
    image

  • 六条指令周期时长约 6 * 1 / 72000000 * 10^9=83.33ns约等于142.5-7.5=85ns

结论

  • 为了兼容多种IIC设备,在使用模拟IIC程序时,IIC停止等信号SDA、SCL间翻转应加适当延时,避免无法识别的情况。
  • 在此情况下应确保翻转延时大于142.5ns的极限延时,实际使用中应留有余量,可使用1us等常见延时。
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);
}