ST/STM32F103C8

STM32F103C8 - UART(Interrupt)

engineer4ever 2025. 8. 8. 09:48

 

MCU
STM32F103(ST)
IDE
Atollic(TrueSTUDIO), STM32CubeMX
목표
HAL driver를 사용하여 UART를 2개 열어서 interrupt mode로 서로 TX-RX를 주고 받게 한다.

 

1. STM32CubeMX : UART-Interrupt(1) 설정

- 'Pinout & Configuration' Tab으로 이동

1) Connectivity 선택

2) USART1 항목 선택

- Mode : Asynchronous, Synchronous 등

- Hardware Flow Control : Disable

- PA9(USART1_TX), PA10(USART1_RX) 자동 할당(녹색 표시)

3) USART2 도 똑같이 설정

 

- Parameter Settings 확인

1) Baud Rate : 115200 Bits/s

2) Word Length : 8 Bits

3) Parity : None

4) Stop Bits : 1

 

- NVIC Settings 확인

1) NVIC 선택

2) USART1 global interrupt : Enabled에 체크

 

- GENERATE CODE 클릭


2. ATOLLIC 실행

 

- main() : 변수 선언

int main(void)
{
  /* USER CODE BEGIN 1 */
	HAL_StatusTypeDef status = HAL_ERROR;

	int i = 0;

	char tx_data[62] = {};
	char rx_data[60] = {};
  /* USER CODE END 1 */
 

- main() : 실행 코드

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_RTC_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
for(i = 0 ; i < 60 ; i++)
{
	tx_data[i] = i+48;
}
status = HAL_UART_Transmit_IT(&huart1, tx_data, 60);

if(status == HAL_OK)
{
	HAL_UART_Receive_IT(&huart1, rx_data, 60);
}
else
{
	__HAL_UART_CLEAR_OREFLAG(&huart2); 
}

for(i = 0 ; i < 60 ; i++)
{
	printf("%c ", rx_data[i]);
}

/* USER CODE END 2 */
 

- 일정 사이즈(60)개가 들어와야 인터럽트 발생. 59 or 61개가 들어오면 정상적인 동작을 기대 할 수 없음

- 위와 같이 60개 보내고 60개 받을때는 문제 없이 동작하는 것 처럼 보이나, 내가 컨트롤 할 수 없는 Delay가 생기면 Overrun Error 발생될 수 있음(데이터가 들어오면 처리 해야 하는데, delay 때문에 처리는 못하고 데이터가 또 들어오면 Overrun)


3. STM32CubeMX : UART-Interrupt(2) 설정

- Configuration은 위와 동일

- USART1 NVIC enable 할 것

 

4. ATOLLIC 실행

 

- stm32f7xx_it.c : USART1_IRQHandler 생성됨

void USART1_IRQHandler(void)
{
	/* USER CODE BEGIN USART1_IRQn 0 */

	/* USER CODE END USART1_IRQn 0 */
	HAL_UART_IRQHandler(&huart1);
	/* USER CODE BEGIN USART1_IRQn 1 */

	/* USER CODE END USART1_IRQn 1 */
}
 

- USART1_IRQHandler 수정

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
	if((huart1.Instance->ISR & UART_FLAG_RXNE) != RESET)
	{
		rx_data[rx_index++] =  huart1.Instance->RDR;
	}

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}
 

위와 같이 rx 데이터가 들어올 때 바로 읽어야 Overrun Error 발생 하지 않음

 

'ST > STM32F103C8' 카테고리의 다른 글

STM32F103C8 - printf()를 이용하여 UART로 문자열 출력  (0) 2025.08.08
STM32F103C8 - UART(DMA)  (3) 2025.08.08
STM32F103C8 - UART(Polling)  (1) 2025.08.08
STM32F103C8 - GPIO(EXTI)  (2) 2025.08.08
STM32F103C8 - GPIO  (0) 2025.08.08