[STM32] USB를 통한 printf 사용법

Eugene CHOI·2021년 10월 5일
1

STM32

목록 보기
5/8
post-thumbnail

저는 기존에 mbed-os 2.0~6.0을 사용하여 nucleo 보드를 프로그래밍 하여 왔습니다.
일반적으로 별도의 설정 없이 프로그램에 사용되는 usb 케이블을 통하여 uart 통신을 할 수 있었습니다.
하지만, stm32 cube를 이용해서 할 때는 직접 몇 가지 설정을 해 주어야 usb를 이용하여 printf 함수를 사용 가능합니다.

제가 찾아보았을 때는 모두 CDC 기능을 사용하여 디버깅을 하였습니다. 그런데 누락된 설명도 많고 저는 능력이 부족한지 구현할 수가 없어 고민하던 차에 STM32CubeIDE를 이용한 STM32 따라하기 책에서 방법을 찾았습니다. HSE clock이나 OTG 설정을 할 필요가 없기 때문에 훨씬 좋은 방법 같습니다.

모든 설정 과정과 이미지 포함하였습니다.

이 포스팅은 STM32F401RE 보드를 사용하였습니다.


1. Serial Wire 3핀 설정


System Core - SYS에서 Debug mode를 Trace Asynchronous Sw로 설정하여 아래와 같이 3개의 핀이 설정되도록 합니다.

2. USART 설정


위 이미지는 stm32-nucleo-64데이터 시트 중 일부를 발췌한 이미지입니다. 잘 읽어보면 UART2가 ST-LINK와 default로 연결되어 있음을 알 수 있습니다. 그래서 D0(PA3, USART2_RX)와 D1(PA2, UART2_TX)는 물리적으로 연결되어 있지 않은 NC 상태입니다. 처음 사용할 땐 이 사실을 모르고 D0, D1핀을 통해서 uart 통신을 시도한다고 고생했습니다...
그래서 USART2 포트를 통해 USB통신을 사용할 수 있습니다. 다음과 같이 Asynchronous mode로 활성화시켜줍니다. 기타 파라미터는 굳이 바꾸지 않고 기본값으로 사용하겠습니다.

3. Clock 설정


F401보드에서 내부 클럭으로 사용가능한 최대 클럭은 84MHz이지만, 적당히 72MHz로 설정하였습니다. 중요하진 않습니다만 클럭이 맞지 않는다면 경고창이 발생합니다. 조합이 불가능한 clock이 아니면 solver가 자동으로 조합을 찾아줍니다.

4. 매크로 추가

다음과 같은 코드를 UER CODE BEGIN 0 영역에 추가하여 줍니다.
GNU의 C컴파일러를 사용한다면 위의 시그니쳐를 아니라면 아래의 시그니쳐를 사용하도록 설정하고 printf 함수가 USART2를 통하여 출력되도록 포팅 코드를 작성합니다.

개개인이 사용하는 보드의 USART 포트에 따라서 &huart2 부분을 변경하여야 합니다.

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

/**
 * @brief Retargets the C library printf function to the USART
 * @param None
 * @retval None
 */
PUTCHAR_PROTOTYPE{
	if (ch == '\n') HAL_UART_Transmit(&huart2, (uint8_t*)"\r", 1, 0xFFFF);
	HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, 0xFFFF);
	return ch;
}

5. 예제 코드 작성

while문 안의 코드는 다음과 같이 두 줄을 작성해줍니다. 단순히 테스트용 printf 함수와 1000ms 동안 delay를 줄 수 있는 HAL 함수입니다.

/* USER CODE BEGIN WHILE */
while (1){
  printf("Hello World!\r\n");
  HAL_Delay(1000-1);
  /* USER CODE END WHILE */
  /* USER CODE BEGIN 3 */
}
  /* USER CODE END 3 */

6. PC와 통신

장치 관리자에서 STLink가 연결 된 통신 포트를 확인합니다. 저는 COM6에 연결되었군요. 이 포트는 컴퓨터마다 다릅니다.

일반적으로 Tera Term을 사용하는데 저는 EBTerminal을 사용하고 있습니다. 각자 편한 터미널 프로그램을 사용하시면 됩니다.
기본 설정대로 baudrate 115,200으로 설정하고 포트를 열어주면 다음과 같이 정상적으로 입력이 들어오는 것을 확인할 수 있습니다.

profile
Hi, my name is Eugene CHOI the Automotive MCU FW developer.

0개의 댓글