目前發現是因為 I2C_CheckEvent(I2C1, I2C_EVENT_xxxxxxxxxxx)

因為未知的原因, 某些flag是會跳起來的, 並不是完全按照範例所想的每個bit不差.

而這個function只要有一個bit不一樣他就判斷錯誤.

因此我把I2C_CheckEvent換成了I2C_GetStatus.

順便在發送過程中加入了Times counting機制. 讓他不容易卡死在迴圈內.

原本的I2C_CheckEvent是直接比對狀態, 回覆正確或是錯誤.

I2C_GetStatus的差異在於他會回傳SR1+SR2的內容, 以方便程式彈性使用.

 

 

/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);

/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

/* Send EEPROM address for write */
I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);

/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

 

以上的原始code由下面的do-while取代

LoopFlag1 = 0x7F; //作127次都沒成功就放棄.

do{
       LoopFlag2 = 0x30;
       /* Send START condition */
       I2C_GenerateSTART(I2C1, ENABLE);
       /* Test on EV5 and clear it */
       while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  

       SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);
       /* Send EEPROM address for write */
       I2C_Send7bitAddress(I2C1, iDEVICE_ADDRESS, I2C_Direction_Transmitter);

       do{
              I2CStatus = I2C_GetStatus(I2C1);
              // pData[LoopFlag2] = I2CStatus;
              if((I2CStatus & I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)
              {
                     LoopFlag2 = 0;
                     LoopFlag1 = 0;
              }
              else
              {
                     LoopFlag2--;
                     I2C_ClearFlag(I2C1, I2C_FLAG_AF);
              }

       }while(LoopFlag2);

}while(LoopFlag1);

 

u32 I2C_GetStatus(I2C_TypeDef* I2Cx)
{
       vu32 Status, bflag1, bflag2;

       /* Read the I2Cx status register */
       bflag1 = I2Cx->SR1;
       bflag2 = I2Cx->SR2;
       bflag2 <<= 16;

       /* Get the last event value from I2C status register */
       Status = (bflag1 | bflag2) & 0x00FFFFFF;

       /* Return status */
       return Status;
}

 

 

 

 

相關文章