hzcmlan 发表于 2024-1-18 16:38:58

FM33LG0系列硬件I2C

在使用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;
    }
}

页: [1]
查看完整版本: FM33LG0系列硬件I2C