问答

汇集网友智慧,解决技术难题

21ic问答首页 - N32WB452CEQ6单片机I2C异常

国产芯片 单片机

N32WB452CEQ6单片机I2C异常

ylq14332232025-04-24
在多次使用I2C和从机通信中,发现经常会有单片机I2C开始条件执行过后,状态寄存器为0的异常情况,经抓过波形发现单片机确实没有发出开始条件,各位大佬,帮忙看看代码是不会有什么问题uint8_t  i2c_master_recv(u8* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead)
{
                if(NumByteToRead > 1)
                {
                        /** Disable Acknowledgement */
                        I2C_ConfigAck(I2C2, ENABLE);
                }
                I2CTimeout = I2CT_LONG_TIMEOUT;
    while (I2C_GetFlag(I2C2, I2C_FLAG_BUSY))
    {
                        if((I2CTimeout --) == 0)
                        {
        I2C_TIMEOUT_UserCallback(MASTER_BUSY);                               
                                return 0;
                        }                       
    }               
    /** Send START condition */               
    // send start   
//                I2C_Enable(I2C2,DISABLE);
//                I2C_Enable(I2C2,ENABLE);
    I2C_GenerateStart(I2C2, ENABLE);
                I2CTimeout = I2CT_LONG_TIMEOUT;
    /** Test on EV5 and clear it */
    while (!I2C_CheckEvent(I2C2, I2C_EVT_MASTER_MODE_FLAG))
    {
                        if((I2CTimeout --) == 0)
                        {
        I2C_TIMEOUT_UserCallback(MASTER_MODE);                               
                                return 0;
                        }
    }
                /** Send write address for write */
    I2C_SendAddr7bit(I2C2, 0x40, I2C_DIRECTION_SEND);
    /** Test on EV6 and clear it */
    I2CTimeout = I2CT_LONG_TIMEOUT;
    while (!I2C_CheckEvent(I2C2, I2C_EVT_MASTER_TXMODE_FLAG))
    {
                        if((I2CTimeout --) == 0)
                        {
        I2C_TIMEOUT_UserCallback(MASTER_TXMODE);
                                return 0;
                        }
    }
                I2C_Enable(I2C2, ENABLE);
                I2C_SendData(I2C2, ReadAddr);
//    /** Test on EV8 and clear it */
    I2CTimeout = I2CT_LONG_TIMEOUT;
    while (!I2C_CheckEvent(I2C2, I2C_EVT_MASTER_DATA_SENDED))
    {
                        if((I2CTimeout --) == 0)
                        {
        I2C_TIMEOUT_UserCallback(MASTER_SENDING);
                                return 0;
                        }
    }
                /** Send STRAT condition a second time */
    I2C_GenerateStart(I2C2, ENABLE);
//    /** Test on EV5 and clear it */
    I2CTimeout = I2CT_LONG_TIMEOUT;
    while (!I2C_CheckEvent(I2C2, I2C_EVT_MASTER_MODE_FLAG))
    {
      if((I2CTimeout --) == 0)
                        {
        I2C_TIMEOUT_UserCallback(MASTER_MODE);
                                return 0;
                        }
    }
//                /** Send EEPROM address for read */
    I2C_SendAddr7bit(I2C2, 0x41, I2C_DIRECTION_RECV);
    /* Test on EV6 and clear it */
    I2CTimeout = I2CT_LONG_TIMEOUT;
                while (!I2C_GetFlag(I2C2, I2C_FLAG_ADDRF))
    {
        if((I2CTimeout --) == 0)
        {
            I2C_TIMEOUT_UserCallback(MASTER_BYTEF);
                                                return 0;
        }
    }
                if(NumByteToRead == 1)
                {
                        /** Disable Acknowledgement */
                        I2C_ConfigAck(I2C2, DISABLE);
                        (void)(I2C2->STS1); /// clear ADDR
                        (void)(I2C2->STS2);
                        I2C_GenerateStop(I2C2, ENABLE);
                }
                else
                {
                        I2C_ConfigAck(I2C2, ENABLE);
                        (void)(I2C2->STS1);
                        (void)(I2C2->STS2);
                        while(NumByteToRead)
                        {                               
                                if(NumByteToRead == 1)
                                {
                                        /** Disable Acknowledgement */
                                        I2C_ConfigAck(I2C2, DISABLE);
                                        I2C_GenerateStop(I2C2, ENABLE);
                                }
                                /** Wait until RXNE flag is set */
                                I2CTimeout = I2CT_LONG_TIMEOUT;
                                while (!I2C_GetFlag(I2C2, I2C_FLAG_RXDATNE))
                                {
                                        if((I2CTimeout --) == 0)
                                        {
                                                I2C_TIMEOUT_UserCallback(MASTER_BYTEF);
                                                return 0;
                                        }
                                }
                                /** Read data from DAT */
                                /** Read a byte from the EEPROM */
                                *pBuffer++ = I2C_RecvData(I2C2);
                                NumByteToRead--;                       
                        }
                        //I2C_GenerateStop(I2C2, ENABLE);
                }
                return 1;
}

回答 +关注 0
44人浏览 1人回答问题 分享 举报
1 个回答

您需要登录后才可以回复 登录 | 注册