본문 바로가기
임베디드 개발/STM32 (ARM Cortex-M)

STM32 , UART 통신 사용하여 시리얼 모니터에 Hello world ! 출력하기 [ UART 통신 정의 ]

by eteo 2022. 5. 22.

시리얼 통신 중 UART 통신에 대한 정리

 

UART (Universal Asynchronous Receiver Transmitter, 범용 비동기식 직렬 포트): PC와 타겟보드가 통신할 때 가장 기본으로 사용하는 포트. Windows 컴퓨터에서는 제어판 장치관리자의 COM으로 시작하는 포트가 UART 통신 포트에 해당

 

장점 : 많은 CPU와 PC에 기본적으로 달려있어 호환성이 좋다.

단점 : 1대1 통신만 가능하다.

 

STM32보드에는 비동기식 UART 포트와 동기/비동기가 모두 가능한 USART 포트가 있으며 둘의 차이는 클락 펄스이다.

 

동기 : 별도의 클락핀이 추가로 필요하다. 전송속도가 빠르다. 데이터 송수신 효율이 좋다.

비동기 : 클락없이 데이터만 보내기 때문에 8 Bit의 데이터마다 Start Bit 와 Stop Bit 가 필요하다. 오류검출을 위한 패리티 비트가 추가될 수도 있다. 송신측과 수신측이 보드레이트(Baud Rate/Bps)를 미리 맞춘다.

 

UART/USART 통신은 기본적으로 TX, RX, GND 만 연결되어 있으면 가능하다. TX와 RX는 데이터를 주고받는 쪽이 교차로 연결하고 같은 GND에 물려있으면 된다. 또한 송신과 수신을 위한 선이 따로 존재하므로 Full-Duplex 전이중 통신방식이다.

 

내가 사용하는 STM32F429ZI 보드는 MCU 파트와 ST-Link 파트가 UART 인터페이스로 연결되어있고 ST-Link 파트는 PC와 USB 인터페이스로 연결되어있기 때문에 다른 모듈을 사용할 필요 없이 마이크로 5핀 케이블을 꼽는 것 만으로 PC와 UART 통신이 가능하다.

 

만약 이런 하드웨어가 내장되어 있지 않은 보드를 사용한다면 FTDI (USB to TTL / USB to Serial / USB to UART) 라고 불리는 모듈을 사용하고 칩셋에 맞는 드라이버가 PC에 깔려있다면 통신이 가능하다.

 

 

먼저 시리얼 모니터로 사용할 프로그램으로 마켓플레이스에서 TM Termianl 이라는 플러그인을 다운받아 사용하겠습니다.

 

 

 

Help- Eclipse Marketplace

 

 

 

 

 

terminal 검색 후 설치

 

 

설치 후 재시작 하면 사용 가능

 

 

 

다음 MX툴에서 아래와 같이 기본적인 설정을 해준다.

 

STM32 Nucleo-F429 보드는 MCU파트와 ST-Link 파트가 USART3 인터페이스를 사용하여 연결되어 있고 ST-Link 파트에선 PC와 USB인터페이스로 연결된다.

 

 

 

USART는 동기식 방식도 가능하다는 의미. Interrupt 방식으로 사용할 거기 때문에 NVIC Settings에 Enabled를 체크 해주었고 만약 Polling 폴링 방식으로 사용할 거라면 체크하지 않아도 된다. (참고. Polling 방식 사용시 Interrupt 방식과 달리 HAL_UART_Transmit 함수를 사용하고 마지막 매개변수로 timeout이 추가됨)

 

 

Parameter Settings 는 그대로 둔다.

 

 

 

 

 

 

Generate Code 를 하면

 

 

 

 

메인 함수 내에 USART3 초기설정 함수가 들어간 것을 확인할 수 있다.

 

 

 

 

소스코드

  /* USER CODE BEGIN 2 */
  uint8_t str[] = "Hello, World!\n\r";
  /* USER CODE END 2 */

line feed, carriage return 포함한다.

 

 

 

 

while문 내

    /* USER CODE BEGIN WHILE */
  while (1)
  {
  	  HAL_UART_Transmit_IT(&huart3, str, sizeof(str));
	  HAL_Delay(1000-1);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

HAL_UART_Transmit_IT 를 사용한다. 함수의 정의는 Drivers-STM32F4xx_HAL_Driver-Src-stm32f4xx_hal_uart.c 에서 찾을 수 있다.

 

 

HAL_UART_Transmit_IT 함수의 원형 및 설명

HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
/**
  * @brief  Sends an amount of data in non blocking mode.
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
  *         of u16 provided through pData.
  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
  *               the configuration information for the specified UART module.
  * @param  pData Pointer to data buffer (u8 or u16 data elements).
  * @param  Size  Amount of data elements (u8 or u16) to be sent
  * @retval HAL status
  */

첫번째 포인터 매개변수는 메인함수 시작지점의에서 MX_USART3_UART_Init함수를 따라가면 usart.c 파일내에 선언되어 있다. 그 주소를 넘겨주면 된다.

두번째 매개변수는 데이터가 담긴 버퍼의 주소값, 세번째 매개변수는 버퍼의 사이즈이다.

 

 

 

 

 

 

디버그 모드 시작

 

 

 

Window - Show View - Other 선택

 

 

 

 

 

Terminal - Terminal 선택

 

아래 터미널창이 뜨면 버튼 클릭하고

 

STM32의 COM포트 선택 후 OK.

 

장치관리자에서 확인가능.

 

1초마다 Hello world 가 출력되는 것을 확인

 

 

 

 

 

 

 

참고로 Board Seletor 가 아닌 MCU/MPU Selector로 선택했을 때 USART3 을 켜면 엉뚱한 핀을 선택했을 수 있으니 Board Manual 을 보고 직접 수동으로 잡아줘야 한다.

 

 

 

 

 

 

 

 

 

 

 

 

다음은 문자열 리터럴 말고 변수 출력해보기

 

 

 

 

 

소스코드

  /* USER CODE BEGIN 2 */
  char uart_buf[30];
  uint32_t count;
  /* USER CODE END 2 */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  	  memset(uart_buf,0,30);
	  sprintf(uart_buf,"count : %d\n\r", count);
	  HAL_UART_Transmit_IT(&huart3, uart_buf, sizeof(uart_buf));
	  count++;
	  HAL_Delay(1000-1);
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }

sprintf는 버퍼에 포맷을 지정하여 출력(저장)하는 함수이다.

 

 

 

 

테라텀으로도 확인 가능

 

시리얼 모니터를 두 개 동시에 쓰는건 불가능하다.