usart-printf.c
Redirecting printf() to the USART in three lines: the board sends readings over the USB virtual serial port, visible in a terminal at 115200 baud. The retargeting pattern is the same across the STM32 range with HAL.
Hardware
A Blue Pill STM32F103C8T6 (Cortex-M3 @ 72 MHz, 64 KB flash) powered by micro-USB or external 3.3 V; programmed over SWD or the serial bootloader. A USB cable on the board connector (ST-LINK virtual serial port or built-in converter).
Wiring
No wiring needed: USART1 (PA9/PA10) must be wired to a 3.3 V USB-serial adapter (the board has no built-in USB converter)..
How it works
__io_putchar() is called by printf for each character; it forwards it through HAL_UART_Transmit. The serial terminal (minicom, PuTTY, CubeIDE monitor) shows the lines at 115200 8N1.
Running it
STM32CubeIDE project (STM32F103C8) or Arduino (STM32 core): program over SWD (ST-LINK, DAPLink adapter) or the serial bootloader (BOOT0 to 1). Note: PC13 LED is active LOW.
Variants
Use HAL_UART_Transmit_DMA to avoid blocking the CPU, or add interrupt reception + sscanf for a mini protocol.
usart-printf.c
// printf vers USART (le port serie virtuel de la carte).
#include "main.h"
#include <stdio.h>
extern UART_HandleTypeDef huart2; // genere par CubeMX (USART2)
// Redirection de printf vers le HAL (retarget).
int __io_putchar(int ch) {
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
// Variante recentree sur newlib (selon la toolchain) :
// int _write(int f, char *p, int n){ HAL_UART_Transmit(&huart2,(uint8_t*)p,n,100); return n; }
uint32_t t0 = 0;
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init(); // 115200 8N1 dans le .ioc
for (;;) {
if (HAL_GetTick() - t0 >= 1000) {
t0 = HAL_GetTick();
float mesure = 3.3f * (float)HAL_GetTick() / 100000.0f; // exemple
printf("t=%lu ms mesure=%.2f V\r\n",
(unsigned long)HAL_GetTick(), mesure);
}
}
}