반도체, 임베디드 Study/STM32

STM32 - UART 구현 - (3) (Interrupt, 코드 상세 구현)

잇(IT) 2024. 5. 29. 19:57
728x90

https://insoobaik.tistory.com/615

 

 

STM32 - UART 구현 - (2) (Echo, Polling 코드 상세 분석)

https://insoobaik.tistory.com/614 STM32 - UART 구현 - (1)보호되어 있는 글입니다. 내용을 보시려면 비밀번호를 입력하세요.insoobaik.tistory.comUART 통신은 기본적으로 8bit 데이터를 전송하기 때문에 char, uint8_t

insoobaik.tistory.com

echo, polling 모드에 이어 interrupt 모드에 대해 알아볼 것이다.


Interrupt 모드

 

Polling 모드의 경우 CPU가 주기적으로 상태를 확인하고 데이터를 처리해야 하기 때문에 사용량이 높은 반면 Interrupt 모드의 경우 데이터가 도착할 때까지 CPU가 대기하지 않고 다른 작업을 수행할 수 있기 때문에 속도 측면에서 Polling 모드보다 빠르다.

혹은

인터럽트를 사용하기 위해 USART3 global interrupt를 체크해주고 코드를 생성하게 되면

 

위와 같이 USART3에 대한 인터럽트 초기화 함수가 생성된 것을 확인할 수 있다.

 

UART 통신에서 인터럽트를 위해 사용하는 함수는 HAL_UART_Receive(Transmit)_IT 함수를 사용할 수 있다.

Received_IT 함수는 위와 같이 정의되어 있다.

RxCpltCallback 함수는 UART 수신 완료 인터럽트가 발생했을 때 호출된다. 여기서 UART 수신 완료란 의미는 UART 모듈이 데이터 수신을 완료하고, 버퍼에 수신된 데이터를 저장한 상태를 나타낸다.

수신 데이터를 저장할 변수를 생성한다.

Interrupt를 사용하기 위해 main 함수에 Receive_IT 함수를 선언한다.

파라미터 값에 의해 USART3 번에 rx_data 버퍼에 1바이트를 수신한다.

위의 Receive_IT 수신 인터럽트가 발생하여 수신이 완료되면 RxCpltCallback 함수가 실행된다.

현재 USART3을 사용하기 때문에 Callback 함수가 호출된 UART 인스턴스가 USART3인지를 확인하는 조건문이다.

 

Callback 함수 안에 Receive_IT가 한 번 더 작성된 이유는 연속적으로 값을 입력받기 위함이다.

(만약 callback 함수 안에 Receive_IT가 없으면 main 함수에 작성된 Received_IT 함수가 한 번 실행되고, callback 함수가 실행되고 마치게 된다.)

 

Receive_IT 함수가 한번 더 호출되기 때문에 버퍼에 입력 받을 준비를하게 되고, Transmit 함수를 통해 버퍼에 있는 데이터를 전송한다.

Transmit 함수를 통해 버퍼에 저장된 값을 출력하고 Received_IT 함수가 또 실행되었기 때문에 입력을 하게되면 또 다시 Callback 함수가 실행되어 입력값을 계속해서 확인할 수 있는 것이다.

 

만약

size를 전부 2로 바꾸게 되면 버퍼에 입력 데이터가 2바이트가 들어와야 Interrupt가 발생하게 되고, Callback 함수가 호출되어 버퍼에 저장된 2바이트의 데이터를 전송하게 된다.

위 실행 결과를 보게 되면 출력이 두글자씩 되는 것을 확인할 수 있다.

 

결국 Interrupt를 사용하게 되면 파라미터의 조건에 맞게 해당 버퍼에 해당 크기만큼 데이터가 들어와야 인터럽트를 실행한다.

polling과 반대로 CPU가 UART 주변 장치를 계속해서 확인하는 것이 아니라 조건이 충족되야 함수가 실행되기 때문에 속도도 빠르고 CPU 점유율도 낮다. 또한 실시간 데이터를 받아 동작하기 때문에 실시간 데이터를 유실할 확률이 polling보다 낮다.


Receive_IT 함수를 응용해서 아래와 같이 구현할 수 있다.

Receive_IT를 통해 값을 led 버퍼에 값을 입력받아 저장하고, callback 함수에 switch case문을 통해 LED를 제어할 수 있다.

1번이 입력되면 LD1을 2번이 입력되면 LD2를 3번이 입력되면 LD3을 Toggle 시키도록 구현하였다.


Transmit_IT

 

Transmit_IT 함수는 전송 데이터를 비블로킹 즉 비동기식으로 보낸다.

while문을 통해 버퍼에 증가한 counter 값이 저장되고, Transmit_IT 함수를 통해 출력하게 된다.

(memset은 해당 버퍼 메모리 주소의 값을 임의로 변하게 하고, sprintf도 주어진 버퍼에 해당 문자열을 저장한다. 자세한 사항은 따로 찾아보길 바란다.)

 

수신과 마찬가지로

HAL_UART_TxCpltCallback() 함수도 송신이 완료되면 동작하는 Callback 함수다.

위 영상을 보게 되면 송신이 완료 될 때마다 LED가 깜빡이는 것을 확인할 수 있다.

 

 

728x90