STM32与Qt串口助手软硬件结合测试实验

张开发
2026/5/31 9:48:52 15 分钟阅读
STM32与Qt串口助手软硬件结合测试实验
一、实验目的掌握STM32开发板串口USART1的初始化与配置方法理解串口通信的基本原理。学会使用FlyMCU工具向STM32开发板烧录程序掌握开发板下载模式与运行模式的切换方法。实现Qt自制串口助手与STM32开发板的双向通信验证串口收发功能的正确性。通过Qt发送指令控制STM32板载LED灯D0PB5、D1PE5的亮灭完成软硬件结合的功能测试。排查串口通信中的常见问题如端口占用、乱码、指令无响应等提升问题解决能力。二、实验原理2.1串口通信原理串口通信是一种异步串行通信方式通过TX发送端和RX接收端引脚实现数据双向传输需约定统一的通信参数波特率、数据位、校验位、停止位否则会出现通信失败或乱码。本实验采用USART1STM32与USB-TTL模块通信波特率设为115200数据位8位无校验位停止位1位115200 8N1。2.2 STM32串口与LED控制原理STM32F103ZET6开发板的USART1对应引脚为PA9TX和PA10RX通过配置GPIO和USART寄存器实现串口数据的发送与接收板载LED灯D0对应PB5引脚、D1对应PE5引脚通过配置GPIO为推挽输出模式控制引脚电平高低低电平点亮、高电平熄灭实现LED灯的亮灭控制。STM32通过串口中断接收Qt发送的指令0、1、2根据指令执行对应的LED控制逻辑并将执行结果回显给Qt串口助手实现双向交互。2.3工具与环境原理FlyMCU用于向STM32烧录程序需通过手动切换开发板至下载模式BOOT01才能完成程序烧录Qt串口助手用于与STM32通信需使用64位MinGW编译器编译避免串口识别失败同时需关闭其他占用串口的工具如FlyMCU防止端口冲突。三、实验环境3.1硬件环境STM32F103ZET6开发板板载LED灯D0PB5、D1PE5USB-TTL模块带CH340芯片串口交叉线或杜邦线USB数据线用于供电和通信电脑一台Windows 11 64位系统3.2软件环境Keil uVision5用于编写、编译STM32程序生成.hex文件FlyMCU用于向STM32开发板烧录程序Qt Creator 5.14.2带64位MinGW编译器用于运行自制串口助手CH340串口驱动CH34ISER.EXE与电脑系统版本匹配四、实验步骤4.1实验环境搭建安装CH340串口驱动运行CH34ISER.EXE根据电脑操作系统版本选择对应驱动进行安装安装完成后将USB-TTL模块插入电脑在设备管理器中查看串口COMx确认驱动安装成功无黄色感叹号。硬件接线使用杜邦线连接USB-TTL模块与STM32开发板接线原则为“TX接RX、RX接TX、GND共地”具体接线如下注意严禁将USB-TTL的5V引脚与STM32连接避免烧毁开发板。USB-TTL TX → STM32 PA10USART1 RXUSB-TTL RX → STM32 PA9USART1 TXUSB-TTL GND → STM32 GNDUSB-TTL 3.3V → STM32 3.3V为开发板供电Qt串口助手准备确保Qt Creator使用64位MinGW编译器编译串口助手项目修改串口接收readData和发送on_btn_send_clicked函数实现控制字符过滤、自动换行和指令发送功能确保串口参数可设置为115200 8N1。4.2 STM32程序编写与编译(这里注明一下虽然我的keil5代码是中文注释但是会被识别成乱码)打开Keil uVision5创建STM32F103ZET6项目添加main.c、usart.h、usart.c三个文件复制以下正确代码适配D0PB5、D1PE5main.c实现LED初始化、串口初始化开机发送欢迎信息和心跳包。#include stm32f10x.h #include usart.h // 初始化D0(PB5)、D1(PE5)两个板载灯 void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; // 开启GPIOB和GPIOE的时钟必须开 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOE, ENABLE); // 初始化D0PB5 GPIO_InitStructure.GPIO_Pin GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStructure); // 初始化D1PE5修正了之前的错误 GPIO_InitStructure.GPIO_Pin GPIO_Pin_5; GPIO_Init(GPIOE, GPIO_InitStructure); // 这里必须是GPIOE // 默认全部熄灭高电平熄灭低电平点亮 GPIO_SetBits(GPIOB, GPIO_Pin_5); GPIO_SetBits(GPIOE, GPIO_Pin_5); } int main(void) { LED_Init(); USART1_Init(); // 函数名正确无波浪线 // 开机欢迎信息中文正常显示无乱码 USART1_SendString(\r\n); USART1_SendString( STM32 软硬件结合测试就绪 (D0PB5 D1PE5)\r\n); USART1_SendString( 发送 1 → D0亮 \r\n); USART1_SendString( 发送 2 → D1亮 \r\n); USART1_SendString( 发送 0 → 全部灭\r\n); USART1_SendString(\r\n); while(1) { // 每秒发送心跳包 USART1_SendString(STM32 运行中...\r\n); Delay_ms(10000); } }usart.h声明串口初始化、字符串发送、延时函数。#ifndef __USART_H #define __USART_H #include stm32f10x.h void USART1_Init(void); void USART1_SendString(char *str); void Delay_ms(uint32_t ms); #endifusart.c实现串口初始化、中断服务函数接收指令、控制LED、回显、字符串发送和延时功能。#include usart.h // 串口中断服务函数必须正确声明 void USART1_IRQHandler(void); void USART1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // 开启GPIOA和USART1的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE); // 串口引脚初始化 // PA9: USART1_TX GPIO_InitStructure.GPIO_Pin GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); // PA10: USART1_RX GPIO_InitStructure.GPIO_Pin GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, GPIO_InitStructure); // 串口参数配置115200 8N1和Qt完全一致 USART_InitStructure.USART_BaudRate 115200; USART_InitStructure.USART_WordLength USART_WordLength_8b; USART_InitStructure.USART_StopBits USART_StopBits_1; USART_InitStructure.USART_Parity USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, USART_InitStructure); // 串口中断配置必须开否则收不到指令 NVIC_InitStructure.NVIC_IRQChannel USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority 1; NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; NVIC_Init(NVIC_InitStructure); // 使能接收中断 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 使能串口 USART_Cmd(USART1, ENABLE); } // 串口中断接收指令控制灯回显 void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) SET) { uint8_t ch USART_ReceiveData(USART1); // 1. 回显给Qt让Qt收到发送的内容 USART_SendData(USART1, ch); // 2. 指令控制灯 if(ch 0) { GPIO_SetBits(GPIOB, GPIO_Pin_5); // D0灭 GPIO_SetBits(GPIOE, GPIO_Pin_5); // D1灭 USART1_SendString( → 全部灯已灭\r\n); } else if(ch 1) { GPIO_ResetBits(GPIOB, GPIO_Pin_5); // D0亮 GPIO_SetBits(GPIOE, GPIO_Pin_5); // D1灭 USART1_SendString( → D0(PB5) 已亮\r\n); } else if(ch 2) { GPIO_ResetBits(GPIOE, GPIO_Pin_5); // D1亮 GPIO_SetBits(GPIOB, GPIO_Pin_5); // D0灭 USART1_SendString( → D1(PE5) 已亮\r\n); } } } // 串口发送字符串函数 void USART1_SendString(char *str) { while(*str) { USART_SendData(USART1, *str); // 等待发送完成 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) RESET); } } // 毫秒延时函数72MHz系统时钟下1ms延时 void Delay_ms(uint32_t ms) { uint32_t i, j; for(i 0; i ms; i) for(j 0; j 7200; j); }编译项目点击Keil工具栏“魔法棒”在Output选项中勾选“Create HEX File”点击“Build”编译项目确保编译结果显示“0 errors, 0 warnings”生成.hex文件位于Objects文件夹中。4.3 STM32程序烧录关闭所有占用串口的工具Qt、其他串口助手等打开FlyMCU软件。FlyMCU参数设置串口号选择设备管理器中CH340对应的COM口非虚拟串口COM1/COM2。波特率设置为115200。芯片型号选择“STM32F103ZET6”。HEX文件点击“打开”选择Keil生成的.hex文件。其他参数数据位8位、无校验位、停止位1位勾选“DTR/RTS自动复位”辅助复位开发板。开发板进入下载模式先断开开发板电源拔掉USB线。按住开发板上的BOOT0按键不放再按住RESET按键不放。先松开RESET按键等待1-2秒后再松开BOOT0按键此时开发板进入下载模式。烧录程序点击FlyMCU中的“开始编程”等待烧录完成烧录日志显示“烧录完成校验成功”即为烧录成功。烧录完成后关闭FlyMCU释放串口将开发板切回正常运行模式按住RESET按键松开BOOT0按键再松开RESET按键开发板重启并运行烧录的程序。4.4软硬件结合功能测试打开Qt串口助手进行串口设置点击“打开串口”确认串口打开成功状态显示“串口已打开”。串口号选择CH340对应的COM口与FlyMCU中选择的一致。波特率115200数据位8位校验位无停止位1位。验证开发板自动发送功能Qt接收区应每秒收到开发板发送的心跳包“STM32 运行中...”同时收到开机欢迎信息说明串口通信正常。验证LED灯控制功能在Qt发送框输入“1”点击发送观察开发板D0灯PB5是否点亮Qt接收区是否收到回显“1 → D0(PB5) 已亮”。在Qt发送框输入“2”点击发送观察开发板D1灯PE5是否点亮Qt接收区是否收到回显“2 → D1(PE5) 已亮”。在Qt发送框输入“0”点击发送观察开发板两个LED灯是否全部熄灭Qt接收区是否收到回显“0 → 全部灯已灭”。异常测试验证串口断开、端口占用等异常情况的处理确保Qt能正确提示“串口已断开”端口被占用时能提示“无法打开串口”。五、实验结果与分析5.1实验结果环境搭建结果CH340驱动安装成功设备管理器中能正常识别串口硬件接线正确开发板供电正常Qt串口助手能正常打开64位编译器编译无错误。程序烧录结果通过FlyMCU手动下载模式成功将程序烧录至STM32开发板烧录日志显示“校验成功”开发板能正常重启运行。串口通信结果Qt串口助手能正常接收开发板发送的欢迎信息和心跳包无乱码、不刷屏开发板能正常接收Qt发送的指令无丢失。LED控制结果发送“1”时D0灯亮、D1灯灭发送“2”时D1灯亮、D0灯灭发送“0”时两灯全部熄灭回显信息正确符合实验预期。5.2结果分析串口通信成功的关键通信参数波特率、数据位等完全一致接线正确TX与RX交叉连接无端口占用Qt使用64位编译器编译。LED控制无响应的排查本次实验中初期LED无响应原因是PE5引脚初始化错误误配置为GPIOB修正代码后LED控制功能正常说明GPIO初始化的正确性直接影响硬件控制效果。烧录失败的排查初期烧录卡壳原因是开发板未手动进入下载模式BOOT0未接高电平切换至下载模式后烧录成功说明开发板模式切换是烧录的关键步骤。乱码问题的解决Qt接收区出现箭头乱码是因为未过滤串口通信中的控制字符\r、\n修改readData函数过滤控制字符后乱码问题解决。六、实验注意事项硬件接线时严格遵循“TX接RX、RX接TX、GND共地”原则严禁将5V电压接入STM32开发板避免烧毁芯片。烧录程序时必须先关闭所有占用串口的工具如Qt、其他串口助手否则会出现“端口被占用”错误开发板必须手动进入下载模式否则烧录失败。Qt串口助手必须使用64位MinGW编译器编译Win11系统下32位编译器无法正常识别串口导致串口打不开。STM32程序编译时需确保函数名拼写正确、GPIO初始化正确对应LED灯引脚否则会出现串口通信失败或LED控制无响应。串口通信时Qt与STM32的通信参数必须完全一致115200 8N1参数不匹配会导致乱码或无法接收数据。烧录完成后需将开发板切回正常运行模式否则开发板会一直处于下载模式无法运行程序。实验过程中若出现串口无法打开、数据乱码等问题优先排查端口占用、接线、通信参数和代码错误。七、实验总结本次实验完成了STM32与Qt串口助手的软硬件结合测试成功实现了串口双向通信和LED灯控制功能。通过实验掌握了STM32串口初始化、程序烧录的方法理解了串口通信的原理学会了排查串口通信中的常见问题端口占用、乱码、指令无响应等。实验过程中遇到了LED引脚初始化错误、烧录模式切换不当、串口乱码等问题通过修正代码、严格按步骤操作均成功解决。本次实验验证了Qt自制串口助手的功能正确性实现了教材要求的软硬件结合测试目标为后续STM32串口通信的实际应用奠定了基础。同时也认识到实验操作的严谨性至关重要任何一个细节错误如接线错误、参数不匹配都会导致实验失败需耐心排查、逐步验证。

更多文章