본문 바로가기

STM32/touchGFX_STM32

[stm32F746] UART Echo 프로그램

728x90

* 목표 : USART 수신 인터럽트를 이용하여 수신 데이터를 링 버퍼에 저장하고 링 버퍼 데이터를 읽어 송신하는 Echo

 

1. USART1 인터럽트 설정

- 인터럽트 사용하기 위해 enable 설정 / Call HAL handler 체크 해제

NVIC Code generation 설정

 

 

2. 코드 작성

1) 링 버퍼 라이브러리 프로젝트 추가

rb.h
0.00MB
rb.c
0.00MB

2) USART1_IRQHandler() 함수 구현

- stm32f7xx_it.c 파일에 USART1 수신 인터럽트 발생 시 콜백 함수를 호출하고 플래그를 클리어해 주는 코드 작성

 

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
if((__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_RXNE) != RESET))
{
HAL_UART_RxCpltCallback(&huart1);  // 콜백 함수 호출 
__HAL_UART_CLEAR_PEFLAG(&huart1);  // 플래그 클리어
}
  /* USER CODE END USART1_IRQn 0 */
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

 

3) 링 버퍼 정의(main.c)

 

/* USER CODE BEGIN Includes */
#include "rb.h"
/* USER CODE END Includes */

---------------------------------------------------

 

/* USER CODE BEGIN PV */
RingFifo_t gtUart2Fifo;
/* USER CODE END PV */

 

4) HAL_UART_RxCpltCallback() 함수 구현(main.c)

- 수신된 데이터를 읽어 링 버퍼에 저장하는 루틴

 

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
uint8_t rx;

if(UartHandle->Instance == USART1)
{
rx = (uint8_t) (UartHandle->Instance->RDR & (uint8_t) 0x00FF);
RB_write(&gtUart2Fifo, rx);
}
}
/* USER CODE END 4 */

 

5) USART1 수신 인터럽트 활성화 및 링 버퍼 초기화

- __HAL_UART_ENABLE_IT() 함수를 통해 수신 인터럽트 활성화하고, RB_init() 함수로 링 버퍼 크기를 정해주고 링 버퍼를 초기화 함

- 주의할 점 2가지 : 링 버퍼의 크기는 2의 지수승 크기로 정의하고 통신 프로토콜에 맞춰 넉넉하게 할 것 / 링 버퍼 메모리를 할당할 때 malloc 함수를 사용하기 때문에 CSTACK 사이즈를 고려할 것

 

/* USER CODE BEGIN 2 */
  __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);  // 수신 인터럽트 활성화
  if(RB_init(&gtUart2Fifo, 16)) // buffer size is power of 2
  {
  //assert(0);
  }
  /* USER CODE END 2 */

 

6) 데이터 수신 여부 체크 및 데이터 읽어서 전송

- RB_isempty() 함수는 링 버퍼에 데이터가 비어있는지 확인하는 함수. 만약데이터가 수신되어 있다면 '0' 반환.

이 때, RB_read() 함수로 링 버퍼의 데이터를 읽어 HAL_UART_Transmit() 함수로 읽은 데이터를 송신

 

/* USER CODE BEGIN WHILE */
  uint8_t ch;
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  if(!RB_isempty(&gtUart2Fifo))
  {
  ch = RB_read(&gtUart2Fifo);
  HAL_UART_Transmit(&huart1, &ch, 1, 0xFF);
  }
  }
  /* USER CODE END 3 */

 

728x90