1. printf()를 사용하고자 하는 이유
1.1. 코드 길이 축소
UART 통신은 데이터를 송수신 할때 자주 사용하는 통신으로 디버깅이나 현재 로그를 출력하기 위해 자주 사용된다.
기본적으로 STM32에서 UART를 이용하여 데이터를 PC에 전송할 때 HAL_UART_Transmit() 함수를 사용하지만, 필요한 인수가 4개(통신할 UART, 전송할 메세지, 메세지 길이, 타임아웃 시간) 이므로 자주 사용하는 함수임에도 사용이 매우 불편하다. 그러므로, C언어를 사용할 때 부터 자주 사용하였던 printf()함수로 대체하여 기본 HAL_UART_Transmit() 함수보다 편하게 사용하고자 한다.
// 기존 UART 통신 함수 사용
char* Message = "Hello world";
HAL_UART_Transmit(&huart3, Message, strlen(Message),5);
// printf() 함수 사용하여 UART 통신
printf("Hello world");
위 코드를 에서 확인 할 수 있듯이 코드의 크기를 많이 줄일 수 있다.
1.2. 기존 printf() 함수의 포멧 기능 사용
printf()를 사용하는 가장 중요한 이유라고 할 수 있다. 가끔 특정 상황에서 디버깅하기 위해 변수의 값을 출력 하고자 할 때, 기존 HAL_UART_Transmit() 함수로는 출력하기에 많이 불편하다. 그러므로, printf() 함수를 통해 변수의 값을 출력을 편하게 하고자 한다.
int num = 10;
// num변수의 값을 UART로 출력
printf("num : %d", &num);
2. 사전 작업
2.1. PC와 통신하는 UART 확인
PC와 통신하는 UART는 사용하는 Board에 따라 다르게 설정되어 있을 수 있다. 제가 사용하는 Nucleo-F429ZI 보드는 UART3가 PC와 통신하고 있음을 확인 할 수 있다.

대부분 많이 사용하는 Nucleo-F103RB 보드는 UART2를 통해 PC와 통신하고 있음을 확인 할 수 있다.

2.2. __io_putchar() 함수 작성
printf() 함수 내에서 __io_putchar() 함수가 호출되지만, STM32 프로젝트 내에서 __io_putchar() 함수가 작성되어 있지 않다. 해당 함수가 작성되어 있지 않음을 "{프로젝트 경로}/Core/Src/syscalls.c" 폴더 내에서 확인 할 수 있다.


위에서 확인 할 수 있듯이, __io_putchar() 함수가 선언은 되어 있지만 동작을 위한 몸체가 없는 것을 확인할 수 있다. 또한 함수 선언에 extern이 붙어 있어 다른 파일에서 해당 함수를 작성 할 수 있도록 한 것을 확인 할 수 있다. 그러므로 해당 함수를 main.c 파일에서 작성 해 줄 것이다.
여기서 제일 중요한 것은 2.1. 에서 확인한 UART를 사용해야한다는 것이다.
저는 UART3 이므로 huart3를 사용하였다.
__io_putchar() 함수
입력 번수 ch : 출력 하고자 하는 문자
반환 값 : 출력 성공 시 출력한 문자, 출력 실패시 0

/* USER CODE BEGIN 4 */
int __io_putchar(int ch){
// UART3에 ch에 있는 문자 1개를 1ms내 전송
if(HAL_UART_Transmit(&huart3, &ch, 1 ,1) != HAL_OK)
return 0; //출력 실패 시 0 리턴
return ch; //출력 성공 시 출력한 데이터 리턴
}
/* USER CODE END 4 */
3. 테스트

/* USER CODE BEGIN WHILE */
size_t count = 0;
while (1)
{
printf("[%d] Hello world\r\n", count);
++count;
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
위 코드 실행 시 정상적 출력 되는 것을 확인 할 수 있다.

4. 참고 사항
4.1. C++ 에서 printf() 함수 사용
'Embedded > STM32' 카테고리의 다른 글
[STM32] 간략한 Timer 사용 방법(1ms 주기 설정) (0) | 2025.02.16 |
---|---|
[STM32] 인터럽트를 이용한 echo UART 통신 (0) | 2024.09.13 |
[STM32] C++에서 printf() 함수 사용 (0) | 2024.09.12 |
[STM32] VScode에서 C++로 빌드 (0) | 2024.09.11 |
STM32위한 vscode 개발 환경 구축 (0) | 2024.08.19 |