<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[STM32]]></title><description><![CDATA[STM32 单片机教程、问题讨论与作品分享]]></description><link>https://www.potatochip.dev/category/5</link><generator>RSS for Node</generator><lastBuildDate>Fri, 09 Oct 2026 19:35:36 GMT</lastBuildDate><atom:link href="https://www.potatochip.dev/category/5.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 01 Oct 2026 15:15:43 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[STM32 UART 串口通信:printf 重定向与中断接收(示例帖)]]></title><description><![CDATA[串口是 STM32 调试的生命线:打印日志、看传感器数据、跟上位机联调都靠它。这篇把最常用的两招讲透:printf 重定向输出,中断方式接收。
1. CubeMX 配置要点

Connectivity → USART1,Mode 选 Asynchronous
波特率 115200,8 数据位、无校验、1 停止位(8N1)
NVIC Settings 里勾选 USART1 global interrupt(中断接收才需要)
PA9(TX)、PA10(RX)接到 USB 转串口模块,注意 TX 接 RX、RX 接 TX,交叉接

2. printf 重定向
C 库的 printf 最终调 fputc,重写它把字符送进串口:
#include &lt;stdio.h&gt;

int fputc(int ch, FILE *f) {
    HAL_UART_Transmit(&amp;huart1, (uint8_t *)&amp;ch, 1, HAL_MAX_DELAY);
    return ch;
}

// main 里直接用
printf("system clock: %lu Hz\r\n", HAL_RCC_GetSysClockFreq());

注意两点:

printf 发 \n 不会自动回车,串口助手里看到满屏阶梯状就改成 \r\n
HAL_MAX_DELAY 是阻塞等待,放在中断里调 printf 会卡死,中断里只做标记

3. 中断接收(推荐做法)
轮询接收会堵住主循环,用中断 + 一字节缓冲:
uint8_t rx_byte;
uint8_t rx_buf[128];
uint8_t rx_len = 0;

void start_uart_rx(void) {
    HAL_UART_Receive_IT(&amp;huart1, &amp;rx_byte, 1); // 启动一次
}

// 每收到 1 字节进一次回调,记得重新挂起下一次接收
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart-&gt;Instance == USART1) {
        if (rx_byte == '\n' || rx_len &gt;= sizeof(rx_buf) - 1) {
            rx_buf[rx_len] = '\0';
            // 在这里处理一行命令,不要做耗时操作
            rx_len = 0;
        } else if (rx_byte != '\r') {
            rx_buf[rx_len++] = rx_byte;
        }
        HAL_UART_Receive_IT(&amp;huart1, &amp;rx_byte, 1); // 关键:重新挂起
    }
}

4. 排障清单



现象
先查




串口无输出
波特率两边是否一致;TX/RX 是否交叉接;GND 有没有共地


输出乱码
波特率/时钟配置,检查 HSE 是否起振


只能收一次
回调里有没有重新调 HAL_UART_Receive_IT


printf 卡死
是否在中断上下文里调用;串口外设时钟开了没



下一篇计划写定时器 PWM 驱动舵机/电机,连载目录见 /series。
]]></description><link>https://www.potatochip.dev/topic/18/stm32-uart-串口通信-printf-重定向与中断接收-示例帖</link><guid isPermaLink="true">https://www.potatochip.dev/topic/18/stm32-uart-串口通信-printf-重定向与中断接收-示例帖</guid><dc:creator><![CDATA[admin]]></dc:creator><pubDate>Thu, 01 Oct 2026 15:15:43 GMT</pubDate></item><item><title><![CDATA[STM32 UART 串口通信:printf 重定向与中断接收(示例帖)]]></title><description><![CDATA[串口是 STM32 调试的生命线:打印日志、看传感器数据、跟上位机联调都靠它。这篇把最常用的两招讲透:printf 重定向输出,中断方式接收。
1. CubeMX 配置要点

Connectivity → USART1,Mode 选 Asynchronous
波特率 115200,8 数据位、无校验、1 停止位(8N1)
NVIC Settings 里勾选 USART1 global interrupt(中断接收才需要)
PA9(TX)、PA10(RX)接到 USB 转串口模块,注意 TX 接 RX、RX 接 TX,交叉接

2. printf 重定向
C 库的 printf 最终调 fputc,重写它把字符送进串口:
#include &lt;stdio.h&gt;

int fputc(int ch, FILE *f) {
    HAL_UART_Transmit(&amp;huart1, (uint8_t *)&amp;ch, 1, HAL_MAX_DELAY);
    return ch;
}

// main 里直接用
printf("system clock: %lu Hz\r\n", HAL_RCC_GetSysClockFreq());

注意两点:

printf 发 \n 不会自动回车,串口助手里看到满屏阶梯状就改成 \r\n
HAL_MAX_DELAY 是阻塞等待,放在中断里调 printf 会卡死,中断里只做标记

3. 中断接收(推荐做法)
轮询接收会堵住主循环,用中断 + 一字节缓冲:
uint8_t rx_byte;
uint8_t rx_buf[128];
uint8_t rx_len = 0;

void start_uart_rx(void) {
    HAL_UART_Receive_IT(&amp;huart1, &amp;rx_byte, 1); // 启动一次
}

// 每收到 1 字节进一次回调,记得重新挂起下一次接收
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart-&gt;Instance == USART1) {
        if (rx_byte == '\n' || rx_len &gt;= sizeof(rx_buf) - 1) {
            rx_buf[rx_len] = '\0';
            // 在这里处理一行命令,不要做耗时操作
            rx_len = 0;
        } else if (rx_byte != '\r') {
            rx_buf[rx_len++] = rx_byte;
        }
        HAL_UART_Receive_IT(&amp;huart1, &amp;rx_byte, 1); // 关键:重新挂起
    }
}

4. 排障清单



现象
先查




串口无输出
波特率两边是否一致;TX/RX 是否交叉接;GND 有没有共地


输出乱码
波特率/时钟配置,检查 HSE 是否起振


只能收一次
回调里有没有重新调 HAL_UART_Receive_IT


printf 卡死
是否在中断上下文里调用;串口外设时钟开了没



下一篇计划写定时器 PWM 驱动舵机/电机,连载目录见 /series。
]]></description><link>https://www.potatochip.dev/topic/17/stm32-uart-串口通信-printf-重定向与中断接收-示例帖</link><guid isPermaLink="true">https://www.potatochip.dev/topic/17/stm32-uart-串口通信-printf-重定向与中断接收-示例帖</guid><dc:creator><![CDATA[admin]]></dc:creator><pubDate>Thu, 01 Oct 2026 15:14:25 GMT</pubDate></item><item><title><![CDATA[STM32 UART 串口通信:printf 重定向与中断接收(示例帖)]]></title><description><![CDATA[串口是 STM32 调试的生命线:打印日志、看传感器数据、跟上位机联调都靠它。这篇把最常用的两招讲透:printf 重定向输出,中断方式接收。
1. CubeMX 配置要点

Connectivity → USART1,Mode 选 Asynchronous
波特率 115200,8 数据位、无校验、1 停止位(8N1)
NVIC Settings 里勾选 USART1 global interrupt(中断接收才需要)
PA9(TX)、PA10(RX)接到 USB 转串口模块,注意 TX 接 RX、RX 接 TX,交叉接

2. printf 重定向
C 库的 printf 最终调 fputc,重写它把字符送进串口:
#include &lt;stdio.h&gt;

int fputc(int ch, FILE *f) {
    HAL_UART_Transmit(&amp;huart1, (uint8_t *)&amp;ch, 1, HAL_MAX_DELAY);
    return ch;
}

// main 里直接用
printf("system clock: %lu Hz\r\n", HAL_RCC_GetSysClockFreq());

注意两点:

printf 发 \n 不会自动回车,串口助手里看到满屏阶梯状就改成 \r\n
HAL_MAX_DELAY 是阻塞等待,放在中断里调 printf 会卡死,中断里只做标记

3. 中断接收(推荐做法)
轮询接收会堵住主循环,用中断 + 一字节缓冲:
uint8_t rx_byte;
uint8_t rx_buf[128];
uint8_t rx_len = 0;

void start_uart_rx(void) {
    HAL_UART_Receive_IT(&amp;huart1, &amp;rx_byte, 1); // 启动一次
}

// 每收到 1 字节进一次回调,记得重新挂起下一次接收
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart-&gt;Instance == USART1) {
        if (rx_byte == '\n' || rx_len &gt;= sizeof(rx_buf) - 1) {
            rx_buf[rx_len] = '\0';
            // 在这里处理一行命令,不要做耗时操作
            rx_len = 0;
        } else if (rx_byte != '\r') {
            rx_buf[rx_len++] = rx_byte;
        }
        HAL_UART_Receive_IT(&amp;huart1, &amp;rx_byte, 1); // 关键:重新挂起
    }
}

4. 排障清单



现象
先查




串口无输出
波特率两边是否一致;TX/RX 是否交叉接;GND 有没有共地


输出乱码
波特率/时钟配置,检查 HSE 是否起振


只能收一次
回调里有没有重新调 HAL_UART_Receive_IT


printf 卡死
是否在中断上下文里调用;串口外设时钟开了没



下一篇计划写定时器 PWM 驱动舵机/电机,连载目录见 /series。
]]></description><link>https://www.potatochip.dev/topic/16/stm32-uart-串口通信-printf-重定向与中断接收-示例帖</link><guid isPermaLink="true">https://www.potatochip.dev/topic/16/stm32-uart-串口通信-printf-重定向与中断接收-示例帖</guid><dc:creator><![CDATA[admin]]></dc:creator><pubDate>Thu, 01 Oct 2026 15:13:11 GMT</pubDate></item><item><title><![CDATA[STM32 HAL 点亮 LED:最小可运行工程(示例帖)]]></title><description><![CDATA[这是论坛的第一篇示例教程,演示代码高亮与发帖模板是否正常工作。
目标
用 STM32 HAL 库点亮一块 LED,理解 GPIO 输出的基本流程。
代码
#include "main.h"

int main(void)
{
	HAL_Init();
	__HAL_RCC_GPIOA_CLK_ENABLE();  // 先开 GPIOA 时钟

	GPIO_InitTypeDef gpio = {0};
	gpio.Pin = GPIO_PIN_5;
	gpio.Mode = GPIO_MODE_OUTPUT_PP;
	gpio.Pull = GPIO_NOPULL;
	gpio.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOA, &amp;gpio);

	while (1) {
		HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
		HAL_Delay(500);
	}
}

要点

操作任何外设前先使能对应总线时钟,这是新手最常踩的坑。
HAL_Delay 依赖 SysTick,确保 HAL_Init() 已调用。
LED 不亮时先用万用表量引脚电平,二分法定位是软件还是硬件问题。

]]></description><link>https://www.potatochip.dev/topic/15/stm32-hal-点亮-led-最小可运行工程-示例帖</link><guid isPermaLink="true">https://www.potatochip.dev/topic/15/stm32-hal-点亮-led-最小可运行工程-示例帖</guid><dc:creator><![CDATA[admin]]></dc:creator><pubDate>Thu, 01 Oct 2026 14:46:54 GMT</pubDate></item><item><title><![CDATA[视频：STM32 入门教程（YouTube 嵌入测试）]]></title><description><![CDATA[测试一下 YouTube 视频在论坛里的嵌入效果，顺便推荐两个 STM32 入门视频。
Getting Started with STM32 Blue Pill

STM32 Blue Pill LED Blink（CubeMX + CubeIDE）
]]></description><link>https://www.potatochip.dev/topic/10/视频-stm32-入门教程-youtube-嵌入测试</link><guid isPermaLink="true">https://www.potatochip.dev/topic/10/视频-stm32-入门教程-youtube-嵌入测试</guid><dc:creator><![CDATA[admin]]></dc:creator><pubDate>Wed, 30 Sep 2026 12:50:56 GMT</pubDate></item><item><title><![CDATA[【实拍】STM32 最小系统板上电，PC13 点灯成功]]></title><description><![CDATA[刚把手头的 STM32F103C8T6 最小系统板翻出来，上电实测点灯。
[image: 最小系统板]
烧录的是之前教程里的 Blink 例程，PC13 接板载 LED，1 秒闪一次，实拍效果如下：

下一步准备把串口打印也调通，有一起玩的可以在楼下交流。
]]></description><link>https://www.potatochip.dev/topic/7/实拍-stm32-最小系统板上电-pc13-点灯成功</link><guid isPermaLink="true">https://www.potatochip.dev/topic/7/实拍-stm32-最小系统板上电-pc13-点灯成功</guid><dc:creator><![CDATA[admin]]></dc:creator><pubDate>Wed, 30 Sep 2026 12:40:27 GMT</pubDate></item><item><title><![CDATA[STM32 新手第一课：环境搭建与点灯]]></title><description><![CDATA[写在前面
这是 potato CHIP 的第一篇测试教程，顺手验证下论坛的排版效果。如果你是第一次玩 STM32，跟着走一遍就能点亮第一颗灯。
需要准备

一块 STM32 开发板（比如 F103 系列任意板子）
ST-LINK / DAPLink 调试器
STM32CubeMX + Keil MDK（ARM）

步骤

打开 STM32CubeMX，新建工程，选择你的芯片型号（如 STM32F103C8T6）。
在 Pinout 界面把板载 LED 对应的 GPIO 设为 GPIO_Output（一般是 PC13）。
Clock Configuration 里把 HCLK 配到 72MHz。
Project Manager 里填工程名、选择 MDK-ARM 工具链，生成代码。
用 Keil 打开工程，在 main.c 的 while(1) 里加：

HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(500);


编译、烧录，灯开始闪烁 —— 恭喜，环境没问题！

常见坑

烧录器驱动没装：ST-LINK 需要装官方驱动。
delay 不准：先检查 HSE 时钟是否使能。


本帖为测试内容，排版如果看着别扭欢迎吐槽。
]]></description><link>https://www.potatochip.dev/topic/2/stm32-新手第一课-环境搭建与点灯</link><guid isPermaLink="true">https://www.potatochip.dev/topic/2/stm32-新手第一课-环境搭建与点灯</guid><dc:creator><![CDATA[admin]]></dc:creator><pubDate>Wed, 30 Sep 2026 12:22:26 GMT</pubDate></item></channel></rss>