STM32 printf重定向串口调试
2026/9/18 13:13:14 网站建设 项目流程

STM32 printf重定向串口调试

在 STM32 开发过程中,经常需要查看程序运行过程中的变量和数据。使用串口将数据发送到电脑,再通过串口调试助手查看,是一种比较方便的调试方式。
本文使用 STM32F1 标准外设库,实现 USART1 的基本配置,并将 printf 重定向到 USART1。配置完成后,可以直接使用 printf() 输出字符串、整数、十六进制数据、浮点数等内容。

一、硬件连接

首先需要准备一个USB转TTL的串口模块用来实现STM32和电脑之间的通信。
这里使用 STM32F1 的 USART1,默认引脚为:PA9 -> USART1_TXPA10 -> USART1_RX;然后将 STM32 的串口引脚与模块上的 TX 和 RX 进行交叉连接,并且要连接上 GND 保证电平一致;

连接完成后,电脑会识别出一个 COM 端口(需要提前安装好CH340驱动),打开串口调试助手,设置为:

也就是常见的115200 8N1

二、USART1 初始化

首先开启 GPIOA 和 USART1 的时钟,然后配置 PA9 和 PA10,最后配置 USART1 的通信参数。
PA9 是 USART1 的发送引脚,因此配置为复用推挽输出;PA10 是接收引脚,配置为上拉输入。
USART1 设置为 115200 波特率、8 位数据位、1 位停止位、无校验、无硬件流控,同时开启发送和接收功能。
完整初始化代码如下:

voidUSART1_Init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);GPIO_InitTypeDef GPIO_InitStructure={0};GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;GPIO_Init(GPIOA,&GPIO_InitStructure);USART_InitTypeDef USART_InitStructure={0};USART_InitStructure.USART_BaudRate=115200;USART_InitStructure.USART_WordLength=USART_WordLength_8b;USART_InitStructure.USART_StopBits=USART_StopBits_1;USART_InitStructure.USART_Parity=USART_Parity_No;USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;USART_Init(USART1,&USART_InitStructure);NVIC_InitTypeDef NVIC_InitStructure={0};NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=5;NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);USART_Cmd(USART1,ENABLE);}

三、实现单字节发送

USART 配置完成后,先实现最基本的单字节发送函数。

voidUSART1_SendByte(uint8_tbyte){while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);USART_SendData(USART1,byte);}

这里等待 USART_FLAG_TXE 置位,表示发送数据寄存器为空,可以写入新的数据。
有了单字节发送函数之后,就可以进一步实现字符串发送:

voidUSART1_SendString(char*str){while(*str){USART1_SendByte(*str++);}}

例如:

USART1_SendString("Hello STM32\r\n");

此时就可以在电脑的串口调试助手中看到输出内容。
不过这种方式只能方便地发送固定字符串,如果需要输出变量,还需要自己进行数据转换。因此通常会进一步使用 printf()。

四、printf重定向

C 标准库中的 printf() 最终会通过 fputc() 输出字符,因此可以重写 fputc(),让每一个字符都通过 USART1 发送。

#include<stdio.h>intfputc(intch,FILE*f){USART1_SendByte((uint8_t)ch);returnch;}

这样就完成了 printf() 到 USART1 的重定向。
同时需要在 Keil 中开启 MicroLIB,以使用精简版 C 运行库,减少程序的代码和内存资源占用。

五、测试代码

配置完成后,可以直接使用下面的代码测试printf是否正常工作。

#include"stm32f10x.h"#include"usart.h"#include<stdio.h>intmain(void){USART1_Init();printf("\r\n");printf("========== STM32 USART Test ==========\r\n");/* 字符串 */printf("String : Hello STM32!\r\n");/* 字符 */printf("Char : %c\r\n",'A');/* 有符号整数 */printf("Int : %d\r\n",-12345);/* 无符号整数 */printf("Uint : %u\r\n",12345);/* 十六进制 */printf("Hex : 0x%X\r\n",0x1234ABCD);/* 八进制 */printf("Octal : %o\r\n",12345);/* 长整数 */printf("Long : %ld\r\n",123456789L);/* 浮点数 */printf("Float : %.2f\r\n",3.1415926);/* 多个变量 */intx=100;inty=200;printf("x = %d, y = %d\r\n",x,y);/* 模拟传感器数据 */int16_tax=1234;int16_tay=-567;int16_taz=16384;printf("ACC: X=%d, Y=%d, Z=%d\r\n",ax,ay,az);/* 模拟状态信息 */uint8_tstate=2;printf("State = %d\r\n",state);printf("=======================================\r\n");while(1){}}

能够正常看到以下内容,就说明 STM32 USART1 配置、USB-TTL 连接、串口参数以及 printf 重定向均已正常工作。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询