前言
本文是本人备赛物联网赛项的学习笔记,主要供本人学习、复习,不是经验分享或教学,若有错误,大佬轻喷。
一、串口核心基本原理
1. 基础核心概念
- 通信类型 :USART 通用同步异步收发器,本场景使用异步串行通信(UART),全双工传输,无需时钟线,仅靠 TX(发送)、RX(接收)两根线完成通信。
- 蓝桥杯标准参数:115200 波特率、8 位数据位、无校验位、1 位停止位(简称 8N1),串口助手必须与该参数完全一致,否则出现乱码。
- 核心标志位 :
- TXE:发送数据寄存器空,标志数据已从 DR 寄存器转入移位寄存器,可写入下一个数据
- TC:发送完成,标志一帧数据完全从移位寄存器发送到 TX 引脚
- HAL 库核心函数 :
HAL_UART_Transmit()阻塞式发送函数,是串口发送的核心底层函数。
2. CT127C 开发板专属硬件链路
本开发板仅 1 个 USB 口,同时承担供电、下载、串口通信功能,完整通信链路如下:STM32WLE5CCU6的USART2_TX(PA2)/RX(PA3) → CH443K模拟开关芯片 → DAPLink调试器MCU → 开发板唯一 USB 口 → 电脑串口助手

CH443K 芯片关键逻辑

CH443K 是单刀双掷模拟开关,用于切换 NODE A/B 两块开发板的串口通道,核心规则:
| SEL 引脚电平 | 选中通道 | 导通链路 | 赛项使用场景 |
|---|---|---|---|
| 低电平 | CH0 | DEBUGGER_TX/RX ↔ A_TXD/RXD(NODE A 板) | 蓝桥杯默认使用,无需手动配置 |
| 高电平 | CH1 | DEBUGGER_TX/RX ↔ B_TXD/RXD(NODE B 板) | 双板通信场景使用 |
注:通道切换由 DAPLink 调试器内置程序完成,比赛时无需我们编写 SEL 引脚控制代码,只需专注 USART2 配置即可。
3. 串口发送完整工作流
- 初始化 GPIO 引脚,将 PA2/PA3 复用为 USART2 的 TX/RX 功能
- 配置 USART2 参数(波特率、数据位等),使能外设时钟与串口外设
- 将要发送的数据写入串口数据寄存器 DR
- 硬件自动将数据转入发送移位寄存器,按设定的波特率,逐位从 TX 引脚发送出去
- 发送完成后,自动置位对应标志位,等待下一次数据写入
二、STM32CubeMX 保姆级配置流程
所有步骤严格对应蓝桥杯 CT127C 开发板(主控 STM32WLE5CCU6),每一步标注截图位置与要求
步骤 1:新建工程,选择目标芯片
- 打开 STM32CubeMX,点击「ACCESS TO MCU SELECTOR」进入芯片选择界面
- 搜索框输入
STM32WLE5CCU6,在右侧列表选中该型号,点击「Start Project」新建工程

步骤 2:调试接口配置(必做,否则程序无法下载)
- 左侧「System Core」下拉菜单,选择「SYS」
- 右侧「Debug」选项,下拉选择「Serial Wire」(串行线调试模式,对应开发板的 DAPLink 调试器)
- 其余参数保持默认


步骤 3:RCC 与时钟树配置(核心,决定波特率是否准确)
3.1 外部晶振配置
- 左侧「System Core」下拉菜单,选择「RCC」
- 右侧「High Speed Clock (HSE)」选项,下拉选择「Crystal/Ceramic Resonator」(外部高速晶振)
- 其余参数保持默认

3.2 时钟树配置(蓝桥杯标准配置)
- 顶部切换到「Clock Configuration」时钟树选项卡
- 按以下参数配置,确保 USART2 时钟源准确:
- HSE 输入频率:32MHz(开发板板载晶振参数)
- 系统主频配置为 48MHz(STM32WLE5CCU6 最大主频)
- USART2 时钟源选择系统时钟,确保时钟频率与波特率计算匹配
- 配置完成后,无红色报错提示

步骤 4:USART2 串口核心配置
4.1 引脚功能映射
- 在芯片引脚预览图中,找到
PA2引脚,左键点击,在弹出菜单中选择「USART2_TX」 - 找到
PA3引脚,左键点击,在弹出菜单中选择「USART2_RX」 - 配置完成后,PA2/PA3 引脚变为绿色高亮状态


4.2 串口参数配置
- 左侧「Connectivity」下拉菜单,选择「USART2」
- 右侧「Mode」选项,下拉选择「Asynchronous」(异步模式,串口通信最常用模式)
- 下方「Configuration」参数栏,按蓝桥杯标准配置:
- Baud Rate(波特率):115200 Bits/s
- Word Length(数据位):8 Bits
- Parity(校验位):None
- Stop Bits(停止位):1
- Data Direction(数据方向):Receive and Transmit(收发双向使能,方便后续扩展接收功能)
- Oversampling(过采样):16 Samples
- 其余参数保持默认

步骤 5:工程管理与代码生成配置(必做,否则 Keil 无法正常打开工程)
5.1 工程基础配置
- 顶部切换到「Project Manager」选项卡
- 「Project」栏目配置:
- Project Name:设置工程名称(严禁使用中文、空格、特殊字符)
- Project Location:设置工程保存路径(严禁使用中文路径)
- Toolchain/IDE:下拉选择「MDK-ARM V5」(对应 Keil5 开发环境)
- 其余参数保持默认
5.2 代码生成规则配置(蓝桥杯开发规范)
- 左侧切换到「Code Generator」选项卡
- 核心勾选项(必须勾选,否则代码结构混乱,无法分文件管理):
- ✅ Generate peripheral initialization as a pair of '.c/.h' files per peripheral(每个外设生成独立的.c/.h 文件,方便代码复用与管理)
- 其余参数保持默认

步骤 6:生成工程代码
- 点击界面右上角「GENERATE CODE」按钮,等待代码生成
- 生成完成后,在弹出的弹窗中点击「Open Project」,直接打开 Keil MDK 工程
三、Keil MDK 保姆级配置与代码编写
代码结构与博客按键模块完全一致:app.c 存放函数实现,app.h 存放函数声明与宏定义 ,所有用户代码必须写在
/* USER CODE BEGIN X */和/* USER CODE END X */之间,否则重新生成 CubeMX 代码时,用户编写的内容会被直接覆盖!
3.1 Keil 工程基础配置(必做,解决 printf 串口打印卡死问题)
- 打开 Keil 工程后,点击界面顶部的魔术棒图标(Options for Target),打开配置界面
- 切换到「Target」选项卡,勾选「Use MicroLIB」
- 点击「OK」保存配置
关键说明:MicroLIB 是 Keil 针对嵌入式系统优化的微型 C 标准库,不勾选该选项时,使用 printf 函数会因半主机模式导致程序卡死,是新手最高频踩坑点。【截图 10:Keil 魔术棒配置界面,需高亮显示 Target 选项卡下 Use MicroLIB 的勾选状态】【截图 11:Keil 工程主界面,需显示左侧工程文件树,包含 usart.c、gpio.c、main.c 等生成的文件】
3.2 新增 app.c 与 app.h 文件(与博客结构一致)
3.2.1 新建 app.h 文件(函数声明与宏定义)
- 在 Keil 左侧工程文件树中,右键点击「Application/User/Core」文件夹,选择「Add New Item to Group 'Application/User/Core'...」
- 在弹出的窗口中,选择「Header File (.h)」,文件名为
app.h,点击「Add」 - 在
app.h文件中,编写以下代码(所有内容写在文件开头即可,无需 USER CODE 块,因为是用户自建文件):
cpp
#ifndef __APP_H
#define __APP_H
// 包含必要的HAL库头文件,提供UART_HandleTypeDef等类型定义
#include "stm32wlxx_hal.h"
// 包含字符串处理头文件,提供strlen函数
#include "string.h"
/****************************************
* 函数名:uart2_send_string
* 功 能:USART2字符串发送封装函数
* 入 参:Data - 要发送的字符串首地址
* 说 明:阻塞式发送,超时时间0xFFFF,避免发送失败卡死
****************************************/
void uart2_send_string(const unsigned char *Data);
#endif
知其所以然:
#ifndef __APP_H/#define __APP_H/#endif:头文件保护机制,防止 app.h 被重复包含导致编译报错- 函数声明放在.h 文件:C 语言要求函数先声明后调用,.h 文件相当于 "函数说明书",让 main.c 等其他文件能识别该函数【截图 12:app.h 文件代码界面,需完整显示所有代码】
3.2.2 新建 app.c 文件(函数实现)
- 在 Keil 左侧工程文件树中,右键点击「Application/User/Core」文件夹,选择「Add New Item to Group 'Application/User/Core'...」
- 在弹出的窗口中,选择「C File (.c)」,文件名为
app.c,点击「Add」 - 在
app.c文件中,编写以下代码(所有内容写在文件开头即可,无需 USER CODE 块,因为是用户自建文件):
cpp
// 包含自建的app.h头文件,确保函数声明与实现一致
#include "app.h"
// 包含标准输入输出头文件,提供printf函数的底层定义
#include "stdio.h"
/****************************************
* 函数名:uart2_send_string
* 功 能:USART2字符串发送封装函数
* 入 参:Data - 要发送的字符串首地址
* 说 明:阻塞式发送,超时时间0xFFFF,避免发送失败卡死
****************************************/
void uart2_send_string(const unsigned char *Data)
{
// 声明串口2句柄(CubeMX自动生成,定义在usart.c文件中)
extern UART_HandleTypeDef huart2;
// HAL库串口发送核心函数:句柄、数据首地址、数据长度、超时时间
HAL_UART_Transmit(&huart2, Data, strlen((const char *)Data), 0xFFFF);
}
/****************************************
* 函数名:fputc
* 功 能:printf函数重定向,实现printf串口输出
* 说 明:重写C库fputc底层函数,将printf输出指向串口2
****************************************/
int fputc(int ch, FILE *f)
{
extern UART_HandleTypeDef huart2;
// 单个字符串口发送
HAL_UART_Transmit(&huart2, (unsigned char *)&ch, 1, 0xFFFF);
return ch;
}
知其所以然:
extern UART_HandleTypeDef huart2;:告诉编译器 huart2 这个变量在其他文件(usart.c)中已经定义过了,这里直接使用即可- fputc 函数:是 C 标准库中 printf 的底层输出函数,重写该函数后,所有 printf 的输出都会通过串口 2 发送出去【截图 13:app.c 文件代码界面,需完整显示所有代码】
3.3 main 函数中调用(仅需包含 app.h,简洁清晰)
打开工程左侧「Application/User/Core」文件夹下的main.c文件,按以下步骤修改:
3.3.1 包含 app.h 头文件
找到/* USER CODE BEGIN Includes */代码块,仅添加#include "app.h"即可,无需再包含其他头文件:
cpp
/* USER CODE BEGIN Includes */
#include "app.h" // 包含自建的app.h,即可使用所有串口发送函数
/* USER CODE END Includes */
3.3.2 主函数循环调用
找到main函数的while(1)主循环,在/* USER CODE BEGIN WHILE */和/* USER CODE END WHILE */之间添加发送代码:
cpp
/* USER CODE BEGIN WHILE */
// 定义测试计数变量,用于格式化输出演示
uint8_t test_cnt = 0;
while (1)
{
// 方式1:调用自定义封装函数,发送固定字符串
uart2_send_string((unsigned char *)"【蓝桥杯CT127C】串口发送测试成功\r\n");
// 方式2:使用printf格式化输出,支持变量、数字等灵活打印(和电脑C语言用法完全一致)
printf("系统运行正常,当前测试次数:%d\r\n", test_cnt);
// 计数变量自增
test_cnt++;
// 延时1000ms,实现1秒发送1次的效果
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
关键说明:
\r\n是串口换行符,必须添加,否则串口助手接收的内容会无换行、显示混乱。【截图 14:main.c 文件代码界面,需完整显示头文件包含与主循环调用代码】
3.4 代码编译与程序下载
- 代码编译:点击 Keil 界面顶部的 Build 按钮(编译图标),等待编译完成
- 程序下载:用 USB 线连接开发板与电脑,点击 Keil 界面顶部的 Download 按钮(下载图标)
四、实验现象验证与串口助手配置)
4.1 电脑端串口助手配置(必须与工程参数完全一致)
- 打开串口调试助手(推荐 SSCOM、野火串口助手等)
- 端口选择:在设备管理器中查看开发板对应的 COM 口,选中该端口
- 串口参数配置(与工程完全匹配):
- 波特率:115200
- 数据位:8
- 停止位:1
- 校验位:无
- 流控:无
- 点击「打开串口」按钮,使能串口接收