linklin 发表于 2024-3-31 23:40:26

模拟I2C主机扫描AT24C02地址遇到的问题

我按照硬汉哥的标准库串行EEPROM读写例程教程移植的检测I2C总线设备代码,先检测完设备后,SDA会一直为低电平导致如果再次调用该函数时会直接return,并且在检测完后进行AT24C02写操作会出错。但是将注释中的代码取消注释后,代码就可以正常运行了。这是为什么?难道是从机(AT24C02)在收到读指令后,响应后SDA电平被拉低,此时发送STOP信号(因为SDA为低电平)无效,只有将一个完整的AT24C02操作完成后才可以有效地发送STOP信号?




uint8_t I2C_CheckDevice(uint8_t _Address)
{
    I2C_SDA_IN();
    I2C_SCL_IN();
    if (I2C_SDA_READ() && I2C_SCL_READ())
    {
      I2C_SDA_OUT();
      I2C_SCL_OUT();
      I2C_Start();
      I2C_SendByte(_Address | I2C_RD);
      if (I2C_WaitAck())
      {
            //I2C_SendByte(0x00);
            I2C_Stop();
            return 1;
      }
      I2C_Stop();
    }
    return 0;
}

eric2013 发表于 2024-4-1 08:36:49

这个是看的什么时候的代码,完全没印象了,建议看新版。

【实战技能】简单易实现的SWD接口烧录目标板挂载的EEPROM,支持AT24C02/04/08/16/32/64/128(2024-03-06)
https://www.armbbs.cn/forum.php? ... d=123223&fromuid=58
(出处: 硬汉嵌入式论坛)


/*
*********************************************************************************************************
*        函 数 名: i2c_CheckDevice
*        功能说明: 检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在
*        形    参:_Address:设备的I2C总线地址
*        返 回 值: 返回值 0 表示正确, 返回1表示未探测到
*********************************************************************************************************
*/
uint8_t i2c_CheckDevice(uint8_t _Address)
{
        uint8_t ucAck;

        if (I2C_SDA_READ() && I2C_SCL_READ())
        {
                i2c_Start();                /* 发送启动信号 */

                /* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */
                i2c_SendByte(_Address | I2C_WR);
                ucAck = i2c_WaitAck();        /* 检测设备的ACK应答 */

                i2c_Stop();                        /* 发送停止信号 */

                return ucAck;
        }
        return 1;        /* I2C总线异常 */
}

linklin 发表于 2024-4-1 09:57:18

eric2013 发表于 2024-4-1 08:36
这个是看的什么时候的代码,完全没印象了,建议看新版。

【实战技能】简单易实现的SWD接口烧录目标板挂 ...

感谢硬汉哥的答疑,我试了一下I2C发送设备地址和写控制是OK的,是我弄成读控制了
页: [1]
查看完整版本: 模拟I2C主机扫描AT24C02地址遇到的问题