【STM32 HAL】多串口printf重定向

前言

在近期项目中,作者需要 STM32 同时向上位机和手机发送数据,传统的 printf 重定向只能输出到一个串口。本文介绍如何实现 printf 同时输出到多个串口

单串口printf重定向

原理

为了使用 printf() 函数进行数据交互,需要重定向 fputc() 函数
这是 printf 内部调用的函数,默认是 __weak 弱定义,便于我们重写

实现

CubeMX配置

与轮询模式配置一致
注意: 中断和 DMA 模式可能导致数据异常,需谨慎使用
在这里插入图片描述

Keil5配置

  1. 勾选 “Use MicroLIB”
  2. 添加头文件stdio.h
  3. 重写fputc()函数
int fputc(int ch,FILE *f)
{
	uint8_t temp[1] = {ch};
	
	HAL_UART_Transmit(&huart1,temp,1,2);// 根据实际情况配置
	return ch;
}

最后,你就能调用 printf() 函数了!!!

多串口printf重定向

fput重定向

int fputc(int ch,FILE *f){
	uint8_t temp[1] = {ch};
	HAL_UART_Transmit(current_huart,temp,1,2);
	return ch;
}

my_usart.c中定义

UART_HandleTypeDef *current_huart = &huart1;

my_usart.h中宏定义

// 定义宏来简化 printf 切换和输出
#define PRINTF_PC(...) do { \
    current_huart = &huart1; \
    printf(__VA_ARGS__); \
} while(0)

#define PRINTF_HC05(...) do { \
    current_huart = &huart2; \
    printf(__VA_ARGS__); \
} while(0)

详解:

  • ‘…’ 是可变参数宏,表示可接收任意参数
  • VA_ARGS’ 会替换为宏调用时传入的实际参数
  • do { … } while(0) 结构确保宏展开后总是作为完整语句执行
  • ‘ \ ’是续行符,用于表示宏定义还未结束

在主循环函数中测试

void loop(void)
{
	PRINTF_PC("PC_TEST\n");
	PRINTF_HC05("HC05_TEST\n");
	HAL_Delay(1000);
}

从此,你就可以使用 PRINTF_PC 和 PRINTF_HC05,轻松实现数据发送到不同的串口了!!!

### Keil V5 STM32 开发环境配置 #### 准备工作 为了顺利开展基于STM32的项目开发,在Keil V5环境中需要完成一系列准备工作。这包括但不限于安装必要的硬件驱动以及设置调试接口,如JLink-OB用于下载程序和USB转TTL模块实现串口通信功能[^1]。 #### 创建新工程 通过STM32CubeMX生成初始化代码并导出至Keil V5作为起点是一个高效的选择。启动STM32CubeMX软件后,选择目标MCU型号(例如STM32H7系列),然后根据具体需求配置外设参数和其他选项。完成后点击“Project”菜单下的“Generate Code”,选择保存路径,并指定IDE为MDK-ARM (Keil)[^3]。 #### 导入工程项目 打开Keil uVision IDE,导入由STM32CubeMX生成的项目文件夹中的`.uvprojx`文件来加载整个工程结构。此时应该能够看到所有源码文件已经被正确添加到了相应的组内。 #### 配置编译器与链接脚本 确保选择了合适的工具链版本和支持包;调整优化级别以适应实际应用场景的要求。对于内存布局,则需编辑链接描述文件(`.ld`)以定义Flash/SRAM分配情况。这部分通常已经在STM32CubeMX生成的过程中自动处理好了,但仍建议开发者仔细检查一遍。 #### 设置调试连接 为了让Keil可以控制目标板上的微控制器执行断点、单步运行等功能,必须建立正确的物理连接——即把PC机经由SWD/JTAG接口同开发板相连。同时还要确认在uVision界面里选用了恰当的目标设备类型及相应驱动程序(比如Segger J-Link Driver)。 #### 测试输出功能 利用printf函数向电脑发送字符串消息是一种简单有效的验证手段。为此先要在stm32_hal_conf.h头文件中开启USE_HAL_UART_REGISTER_CALLBACKS宏定义以便支持回调机制,再调用HAL库提供的UART传输APIs完成最终集成。 ```c // 示例:初始化USART并打印测试信息 #include "main.h" int main(void){ HAL_Init(); SystemClock_Config(); // 系统时钟配置 MX_USART2_UART_Init(); // 初始化 USART2 printf("Hello, world!\r\n"); // 输出测试语句 while (1){ ; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值