查看: 135|回复: 0

FM33LG0系列硬件I2C

[复制链接]

1

主题

2

帖子

85

积分

中级工程师

Rank: 2

积分
85
发表于 2024-1-18 16:38:58 | 显示全部楼层 |阅读模式
在使用FM33LG0系列的I2C时,发现如果从器件的ACK响应不及时,就会导致写入从器件不成功的现象,这种现象用软件GPIO模拟I2C可以延长ACK的判断来解决,但是硬件I2C的第九个时钟的时间是固定的,一旦在第九个时钟来临之前,没有检测到ACK,就会被认为是NACK而退出。

我用了一个方法来骗过从器件,从而解决了从器件ACK响应时间超过SCL的时钟周期的问题。

如下是解决方法,大家可以探讨:
uint8_t I2C_Send_Byte(uint8_t x_byte)
{
    uint16_t delay = 0;
    FL_I2C_Master_WriteTXBuff(I2C, x_byte);
       
    while(!FL_I2C_Master_IsActiveFlag_TXComplete(I2C));

    FL_I2C_Master_ClearFlag_TXComplete(I2C);
       
    if(!FL_I2C_Master_IsActiveFlag_NACK(I2C))
    {
        return 0;
    }
    else                                 //如果检测到NACK
    {
                I2C_SIMGPIOINIT();      //将I2C切换成软件模拟I2C
                while(FL_GPIO_GetInputPin(GPIOA, FL_GPIO_PIN_12))    //检测SDA是否一直为高
                {
                        delay++;
                        FL_DelayUs(1);
                        if(delay >= 2000)                                                //超时时间到了之后
                        {
                                delay = 0;
                                FL_I2C_Master_ClearFlag_NACK(I2C);           //清除NACK中断标志
                                I2C_Init();                                                  //重新配置I2C为硬件模式
                                I2C_Send_Bit(STOPBIT);                              //发送停止                               
                                return 1;                                                     //退出
                        }
                }                                                                                //检测到从机已返回ACK
                FL_GPIO_SetOutputPin(GPIOA,FL_GPIO_PIN_11);           //产生第九个时钟
                FL_DelayUs(5);
                FL_GPIO_ResetOutputPin(GPIOA,FL_GPIO_PIN_11);
                I2C_Init();
        return 0;
    }
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表