xusiwei1236 发表于 2025-7-29 22:31

【STM32U385RG 测评】重定向printf到LPUART(原理图、代码、实验全流程介绍 )

本帖最后由 xusiwei1236 于 2025-7-29 22:38 编辑

本篇将介绍如何在STM32U385上实现 `printf`输出到LPUART1,并通过板载STLink-V3E的虚拟串口将输出内容转发到PC,具体包括原理图解读、项目创建、代码实现、实验验证的完整开发流程。首先介绍了软硬件准备,包括VSCode+CubeMX的软件开发环境、开发板与PC的硬件连接方式,以及LPUART相关的硬件原理图。接着介绍了CubeMX项目的创建步骤,涵盖芯片型号选择、引脚配置、LPUART参数设置、ioc文件保存及CMake项目生成。随后介绍了printf重定向的实现代码,即在VSCode中导入项目后,于 `usart.c`添加 `__io_putchar`函数,实现通过 `LPUART1`发送字符,并在 `main.c`的主循环中添加 `printf`调用进行测试。最后介绍了printf重定向的验证步骤,包括生成elf文件、下载运行elf文件,以及通过MobaXterm串口会话查看输出结果。文档末尾还提供了ST官网文章、CubeMX等工具的参考链接,对相关内容感兴趣的读者,可自行访问相应链接了解更详细的信息。


## 一、准备软硬件

### 1.1 软件环境

开发环境用的是VSCode+CubeMX,搭建方式见上一篇帖子: [【STM32U385RG 测评】搭建基于VSCode的STM32开发环境](https://bbs.21ic.com/icview-3472232-1-1.html)

### 1.2 硬件连接

硬件连接方式如下图所示:

!(data/attachment/forum/202507/29/222320scm9pp8kj3k9gkms.png "image-20250728220602340.png")

通过USB Type-C线连将开发板连接到PC,需要注意的是:

1. 开发板接标有USB STLK的口,如图所示;
2. 有的USB线PC不识别,不是驱动问题,换一根线就可以;

### 1.3 原理图

开发板上带了ST-Link V3E调试器,位于主控芯片STM32U385RGT6Q和STLK USB接口之间,用于实现PC和主控芯片之间的JTAG调试和UART通信,其中UART相关连接部分的原理图如下图所示:

!(data/attachment/forum/202507/29/222333py5r05cklve0ikvv.png "image-20250728221031606.png")

!(data/attachment/forum/202507/29/222342ho0vd78l870l6noq.png "image-20250728221854687.png")

## 二、创建CubeMX项目

### 2.1 选择芯片型号

启动CubeMX,芯片型号STM32U385RG,Start Project,如下图:

!(data/attachment/forum/202507/29/222402p28m9t98rpml1j66.png "image-20250728222332049.png")

### 2.2 配置引脚功能

根据前面的原理图,将PA9和PA10引脚分别配置为LPUART1_TX、LPUART1_RX功能,如下图:

!(data/attachment/forum/202507/29/222414a7hzy9y9khna7xy7.png "image-20250728222523527.png")

### 2.3 配置LPUART参数

首先,找到Connectivity->LPUART1,Mode下拉到Asynchronous,启用LPUART1功能;

然后,修改波特率为115200,如下图:

!(data/attachment/forum/202507/29/222427m9rdd3z7ihhpxqqt.png "image-20250728222842811.png")

### 2.4 保存ioc文件

完成上述配置后,使用CubeMX菜单File->Save as,或者快捷键Ctrl+S,弹出保存ioc文件对话框,

例如,保存到 `E:\DIY\ST\STM32U385\21ic_bbs\LPUART_printf `目录,如下图:

!(data/attachment/forum/202507/29/222440zdfhwwpuu7ufvzkv.png "image-20250728223505087.png")

### 2.5生成CMake项目

切到Project Manager标签页,Toolchain选择CMake,如下图:

!(data/attachment/forum/202507/29/222452v7lhnsn8uthob8zo.png "image-20250728223903306.png")

Code Generator中,勾选Copy only the necessary library fies和Generate peripheral initialization as a pair of '.c/.h' files per peripheral;

!(data/attachment/forum/202507/29/222516ekju3ub6u44x4b3i.png "image-20250728224043571.png")

接着,Generate Code即可生成CMake项目代码。

## 三、实现printf重定向到LPUART

### 3.1 导入CMake项目

在VSCode中,使用STM32插件的Import CMake project菜单,导入项目:

!(data/attachment/forum/202507/29/222607o5yrr34k3ykk0665.png "image-20250729051321917.png")

选择前面创建的目录,`E:\DIY\ST\STM32U385\21ic_bbs\LPUART_printf `,确认导入,在当前窗口打开即可。

### 3.2 实现__io_putchar函数

找到 `usart.c`文件,在末尾添加如下 `__io_putchar`函数:

```c
int __io_putchar(int ch)
{
HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
```

Ctrl+S保存。

### 3.3 添加printf调用

找到 `main.c`,在 `while (1)`循环中添加如下代码:

```c
printf("Hello 21ic, Hello NUCLEO-U385RG-Q!\r\n");
    HAL_Delay(1000);
```

Ctrl+S保存。

## 四、验证printf重定向到LPUART

### 4.1 生成elf文件

在VSCode中,使用CMake插件的生成按钮,生成LPUART_printf.elf文件,如下图:

!(data/attachment/forum/202507/29/222631j4lcr7wco85jfczf.png "image-20250729052100698.png")

构建成功后,可以看到RAM、Flash占用信息:

!(data/attachment/forum/202507/29/222643wv7ywa52yzd5c5ja.png "image-20250729060153505.png")

### 4.2 下载、运行LPUART_printf.elf文件

在VSCode中,使用STM32插件的“运行命令”按钮,下载LPUART_printf.elf到开发板,并复位运行,如下图:

!(data/attachment/forum/202507/29/222656hwo4vw1t0c40n1ez.png "image-20250729052345580.png")

弹出界面中,选择 `CubeProg: Flash project (SWD)`,如下图:

!(data/attachment/forum/202507/29/222711aupa7fsam081zami.png "image-20250729060544137.png")

在MobaXterm中,创建新的Serial会话,参数如下图:

!(data/attachment/forum/202507/29/222725gwi7hwslxsg00jwj.png "image-20250729060433927.png")

点击OK,确认创建串口会话,此时就可以看到输出了:

!(data/attachment/forum/202507/29/222737m9elezfaefwavbbm.png "image-20250729060735506.png")

最后,附上项目开源代码链接:

https://gitcode.com/xusiwei1236/NUCLEO-U385/tree/main/LPUART_printf

## 五、参考链接

1. ST官网文章《使用面向VS Code的STM32扩展简化您的开发过程》: https://www.st.com.cn/content/st_com/zh/campaigns/stm32-vs-code-extension-z11.html
2. STM32CubeMX下载页面: https://www.st.com.cn/zh/development-tools/stm32cubemx.html
3. STM32CubeCLT下载页面: https://www.st.com.cn/zh/development-tools/stm32cubeclt.html
4. ST-MCU-FINDER-PC下载页面:https://www.st.com.cn/zh/development-tools/st-mcu-finder-pc.html
5. VSCode下载页面: https://code.visualstudio.com/Download
6. NUCLEO-U385RG-Q开发板原理图:https://www.st.com.cn/resource/en/schematic_pack/mb1841-u385rgq-e01-schematic.pdf

kkzz 发表于 2025-8-20 08:32

重定义 fputc 函数,将 printf 的输出重定向到 LPUART。

gygp 发表于 2025-8-20 18:03

printf 是阻塞式输出,频繁调用可能导致系统响应延迟

macpherson 发表于 2025-8-20 18:24

使用半主机模式替代硬件串口            

lzmm 发表于 2025-8-20 18:44

如果使用中断接收数据,确保中断优先级设置合理,避免中断嵌套过深。

mmbs 发表于 2025-8-20 19:14

通过重定向printf到LPUART,可以方便地在STM32U385RG上实现调试信息的串口输出。

mnynt121 发表于 2025-8-20 20:28

避免在高优先级任务中频繁打印            

uptown 发表于 2025-8-20 21:05

printf可能使用缓冲区,确保缓冲区足够大,避免溢出。

maqianqu 发表于 2025-8-20 22:34

可通过 DMA 或环形缓冲区优化数据传输效率

biechedan 发表于 2025-8-20 23:00

需注意波特率匹配和中断处理            

vivilyly 发表于 2025-8-21 15:14

#include <stdio.h>

// 重定向 printf 到 LPUART
int fputc(int ch, FILE *f) {
    HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
    return ch;
}

mmbs 发表于 2025-8-21 16:29

支持发送/接收中断,提升实时性。

earlmax 发表于 2025-8-21 17:12

STM32CubeIDE 提供了便捷的配置工具,可快速生成初始化代码。

mattlincoln 发表于 2025-8-21 18:10

重写_write或fputc函数,初始化LPUART,处理时钟和GPIO,注意缓冲区和中断,

bartonalfred 发表于 2025-8-21 18:42

启用LPUART1和printf重定向后,代码增加约2KB Flash占用,RAM增加约100字节

iyoum 发表于 2025-8-21 19:17

通过重定向 fputc 函数,可将其输出改为通过 LPUART 发送数据

tifmill 发表于 2025-8-21 19:46

合理设置LPUART中断优先级,避免被其他高优先级中断抢占。

bestwell 发表于 2025-8-21 21:11

LPUART是低功耗UART,适用于低功耗应用。

sesefadou 发表于 2025-8-21 22:00

结合LPUART1的唤醒功能,实现低功耗模式下的远程升级

pmp 发表于 2025-8-21 22:38

如果缓冲区过小,可能会导致数据丢失或溢出。
页: [1] 2
查看完整版本: 【STM32U385RG 测评】重定向printf到LPUART(原理图、代码、实验全流程介绍 )