본문 바로가기

ARM Life

STM32 I2C 운용 중 HAL_I2C_ERROR_TIMEOUT 발생 관련

현재 개발하고 있는 디바이스에 여러개의 센서가 달려 있고 모두 I2C를 사용하고 있다.

그 중 2개의 센서는 40ms 주기로 번갈아 가며 I2C Transmit/Receive를 해야 하는 상황인데 이번에 GNSS 모듈에 대한 관련 기능을 구현하면서 확인해보니 HAL_I2C_Master_Transmit 실행 부분에서 TIMEOUT 에러가 발생하기 시작했다.

 

- HAL_I2C_GetError 함수로 에러를 확인해 보면 0x20 에러 발생 (HAL_I2C_ERROR_TIMEOUT)

- 아주 랜덤하게 에러가 발생했다. 시작하자마자 발생되기도 하고 5분 정도가 지나서 발생되기도 했다. 

 

두개의 센서 중 하나의 I2C 인터페이싱 코드 부를 삭제하고 테스트해보면 에러가 발생하지 않는다. 아무래도 빠른 속도로 I2C를 수행하다보니 어느 순간 I2C 연결 디바이스가 준비되지 않은 상태에서 송수신을 시도하게 되면 에러가 발생되는 것 같다. 

 

결론적으로 이 문제는 완벽한 해결 방법은 아닌 것 같지만 (Sampling interval 기준 데이터 누락이 매우 Critical한 문제라면...) HAL_I2C_IsDeviceReady() 함수를 이용하여 디바이스 준비 상태를 체크를 해 줌으로써 해결했다. 

 

 

if(HAL_I2C_IsDeviceReady(&hi2c2,slaveAddr,10,100)==HAL_OK)
{

    while(HAL_I2C_Master_Transmit(&hi2c2, (slaveAddr << 1) | 0x00, &regAddr, 1, HAL_MAX_DELAY)!= HAL_OK)

    {

        if (HAL_I2C_GetError(&hi2c2) != HAL_I2C_ERROR_AF)

        {

          Debug_Log("A sensor HAL_I2C_GetError_TX: Read_Waveform.\r\n")

          Error_Handler();

        }

    }

    while(HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY); //Wait for the end of the transfer

   

    while(HAL_I2C_Master_Receive(&hi2c2, (slaveAddr << 1) | 0x01, data, 3, HAL_MAX_DELAY) != HAL_OK)

    {

      ...

    }

}