跳转至内容

STM32

7 主题 7 帖子

STM32 单片机教程、问题讨论与作品分享

此版块可通过开放社交网络使用标识符 [email protected] 关注

  • STM32 UART 串口通信:printf 重定向与中断接收(示例帖)

    1
    0 赞同
    1 帖子
    8 浏览
    A
    串口是 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 <stdio.h> int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&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(&huart1, &rx_byte, 1); // 启动一次 } // 每收到 1 字节进一次回调,记得重新挂起下一次接收 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { if (rx_byte == '\n' || rx_len >= 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(&huart1, &rx_byte, 1); // 关键:重新挂起 } } 4. 排障清单 现象 先查 串口无输出 波特率两边是否一致;TX/RX 是否交叉接;GND 有没有共地 输出乱码 波特率/时钟配置,检查 HSE 是否起振 只能收一次 回调里有没有重新调 HAL_UART_Receive_IT printf 卡死 是否在中断上下文里调用;串口外设时钟开了没 下一篇计划写定时器 PWM 驱动舵机/电机,连载目录见 /series。
  • STM32 UART 串口通信:printf 重定向与中断接收(示例帖)

    1
    0 赞同
    1 帖子
    2 浏览
    A
    串口是 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 <stdio.h> int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&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(&huart1, &rx_byte, 1); // 启动一次 } // 每收到 1 字节进一次回调,记得重新挂起下一次接收 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { if (rx_byte == '\n' || rx_len >= 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(&huart1, &rx_byte, 1); // 关键:重新挂起 } } 4. 排障清单 现象 先查 串口无输出 波特率两边是否一致;TX/RX 是否交叉接;GND 有没有共地 输出乱码 波特率/时钟配置,检查 HSE 是否起振 只能收一次 回调里有没有重新调 HAL_UART_Receive_IT printf 卡死 是否在中断上下文里调用;串口外设时钟开了没 下一篇计划写定时器 PWM 驱动舵机/电机,连载目录见 /series。
  • STM32 UART 串口通信:printf 重定向与中断接收(示例帖)

    1
    0 赞同
    1 帖子
    4 浏览
    A
    串口是 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 <stdio.h> int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&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(&huart1, &rx_byte, 1); // 启动一次 } // 每收到 1 字节进一次回调,记得重新挂起下一次接收 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { if (rx_byte == '\n' || rx_len >= 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(&huart1, &rx_byte, 1); // 关键:重新挂起 } } 4. 排障清单 现象 先查 串口无输出 波特率两边是否一致;TX/RX 是否交叉接;GND 有没有共地 输出乱码 波特率/时钟配置,检查 HSE 是否起振 只能收一次 回调里有没有重新调 HAL_UART_Receive_IT printf 卡死 是否在中断上下文里调用;串口外设时钟开了没 下一篇计划写定时器 PWM 驱动舵机/电机,连载目录见 /series。
  • STM32 HAL 点亮 LED:最小可运行工程(示例帖)

    1
    0 赞同
    1 帖子
    11 浏览
    A
    这是论坛的第一篇示例教程,演示代码高亮与发帖模板是否正常工作。 目标 用 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, &gpio); while (1) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); HAL_Delay(500); } } 要点 操作任何外设前先使能对应总线时钟,这是新手最常踩的坑。 HAL_Delay 依赖 SysTick,确保 HAL_Init() 已调用。 LED 不亮时先用万用表量引脚电平,二分法定位是软件还是硬件问题。
  • 视频:STM32 入门教程(YouTube 嵌入测试)

    1
    0 赞同
    1 帖子
    2 浏览
    A
    测试一下 YouTube 视频在论坛里的嵌入效果,顺便推荐两个 STM32 入门视频。 Getting Started with STM32 Blue Pill STM32 Blue Pill LED Blink(CubeMX + CubeIDE)
  • 【实拍】STM32 最小系统板上电,PC13 点灯成功

    1
    1
    0 赞同
    1 帖子
    8 浏览
    A
    刚把手头的 STM32F103C8T6 最小系统板翻出来,上电实测点灯。 [image: 最小系统板] 烧录的是之前教程里的 Blink 例程,PC13 接板载 LED,1 秒闪一次,实拍效果如下: 下一步准备把串口打印也调通,有一起玩的可以在楼下交流。
  • STM32 新手第一课:环境搭建与点灯

    1
    0 赞同
    1 帖子
    0 浏览
    A
    写在前面 这是 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 时钟是否使能。 本帖为测试内容,排版如果看着别扭欢迎吐槽。