STM32F4VGT6-DISCOVERY:uart1驱动
对于这款板子,官方并没有提供串口例程,只能自行添加。
一、PA9/PA10复用成串口1功能不可用
驱动测试代码如下:
main.c:
#include "main.h"
#include <stdio.h>void usart1_init(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//(1)串口时钟和 GPIO 时钟使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//GPIO口时钟使能, 引脚PA9,PA10可以复用为串口功能RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口UART1时钟使能, 串口1是挂载在 APB2总线下的外设//(2)配置GPIO引脚为复用功能[PA9+PA10]GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//电平翻转速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化 PA9,PA10//(3)配置串口1参数USART_InitStructure.USART_BaudRate = 115200;//波特率USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不使用硬件流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8个数据位USART_Init(USART1, &USART_InitStructure); //初始化串口1//(4) 开启中断并且初始化 NVIC,使能相应中断[接收一个byte触发中断一次]USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//抢占优先级 3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//响应优先级 3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化NVIC寄存器//(5) 使能串口1USART_Cmd(USART1, ENABLE);
}//串口1中断服务函数
void USART1_IRQHandler(void)
{char res;//检查标志位if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){res = USART_ReceiveData(USART1);//收到数据后读出来USART_SendData(USART1,res);//读到数据后立刻发送出去//清空标志位USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}int main(void)
{usart1_init();while(1){;}return 0;
}
固件烧录后,连接PC端串口工具,串口收发功能不可用。原因:PA9/PA10设计给板载USB使用,打开原理如下:

所以,只能换一组GPIO,换成PB6/PB7(原理图上可确认没有其他外设使用),测试代码如下:
#if 0
void usart1_init(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//(1)串口时钟和 GPIO 时钟使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//GPIO口时钟使能, 引脚PA9,PA10可以复用为串口功能RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口UART1时钟使能, 串口1是挂载在 APB2总线下的外设//(2)配置GPIO引脚为复用功能[PA9+PA10]GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//电平翻转速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化 PA9,PA10//(3)配置串口1参数USART_InitStructure.USART_BaudRate = 115200;//波特率USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不使用硬件流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8个数据位USART_Init(USART1, &USART_InitStructure); //初始化串口1//(4) 开启中断并且初始化 NVIC,使能相应中断[接收一个byte触发中断一次]USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//抢占优先级 3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//响应优先级 3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化NVIC寄存器//(5) 使能串口1USART_Cmd(USART1, ENABLE);
}//串口1中断服务函数
void USART1_IRQHandler(void)
{char res;//检查标志位if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){res = USART_ReceiveData(USART1);//收到数据后读出来USART_SendData(USART1,res);//读到数据后立刻发送出去//清空标志位USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}#else
void usart1_init(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//(1)串口时钟和 GPIO 时钟使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //使能GPIOB时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口UART1时钟使能, 串口1是挂载在 APB2总线下的外设//(2)配置GPIO引脚为复用功能[PB6+PB7]GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//电平翻转速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化 PA9,PA10//(3)配置串口1参数USART_InitStructure.USART_BaudRate = 115200;//波特率USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不使用硬件流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8个数据位USART_Init(USART1, &USART_InitStructure); //初始化串口1//(4) 开启中断并且初始化 NVIC,使能相应中断[接收一个byte触发中断一次]USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//抢占优先级 3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//响应优先级 3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化NVIC寄存器//(5) 使能串口1USART_Cmd(USART1, ENABLE);
}//串口1中断服务函数
void USART1_IRQHandler(void)
{char res;STM_EVAL_LEDOn(LED4);//检查标志位if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){res = USART_ReceiveData(USART1);//收到数据后读出来STM_EVAL_LEDOn(LED5);USART_SendData(USART1,res);//读到数据后立刻发送出去//清空标志位USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}
#endifint main(void)
{usart1_init();while(1){;}return 0;
}
板子实物图连接如下:


串口工具测试如下:

二、串口标准输入输出重定向打印实现
直接重写标准输入输出函数的底层接口即可,如下:
| //重写printf底层函数接口 int fputc(int c, FILE *stream) { USART1->DR=c; //发送一个字符 while(!(USART1->SR&1<<7)){} return c; } //重写scanf底层函数接口 int fgetc(FILE *stream) { while(!(USART1->SR&1<<5)){} return USART1->DR; } |
烧录固件,并按reset键,观察串口调试助手上的打印:使用ST-LINK的方式进行烧录

串口助手:

三、完整代码
usart.c
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include <stdio.h>void usart1_init(uint32_t BaudRate)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//(1)串口时钟和 GPIO 时钟使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //使能GPIOB时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口UART1时钟使能, 串口1是挂载在 APB2总线下的外设//(2)配置GPIO引脚为复用功能[PB6+PB7]GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//电平翻转速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化 PA9,PA10//(3)配置串口1参数USART_InitStructure.USART_BaudRate = BaudRate;//波特率USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不使用硬件流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8个数据位USART_Init(USART1, &USART_InitStructure); //初始化串口1//(4) 开启中断并且初始化 NVIC,使能相应中断[接收一个byte触发中断一次]USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//抢占优先级 3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//响应优先级 3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化NVIC寄存器//(5) 使能串口1USART_Cmd(USART1, ENABLE);
}//串口1中断服务函数
void USART1_IRQHandler(void)
{char res;//检查标志位if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){res = USART_ReceiveData(USART1);//收到数据后读出来USART_SendData(USART1,res);//读到数据后立刻发送出去//清空标志位USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}//重写printf底层函数接口
int fputc(int c, FILE *stream)
{USART1->DR=c; //发送一个字符while(!(USART1->SR&1<<7)){}return c;
}//重写scanf底层函数接口
int fgetc(FILE *stream)
{while(!(USART1->SR&1<<5)){}return USART1->DR;
}/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
usart.h
#ifndef __USART__H__
#define __USART__H__void usart1_init(uint32_t BaudRate);#endif /* __USART__H__ */
main.c
#include "usart.h"
#include <stdio.h>int main(void)
{usart1_init(115200);printf("hello world!\n");while(1){;}return 0;
}
注:这款Discovery开发板是基于标准外设库函数来开发的,因此工程中要把串口相关的库函数文件添加进来,如下:

相关文章:
STM32F4VGT6-DISCOVERY:uart1驱动
对于这款板子,官方并没有提供串口例程,只能自行添加。 一、PA9/PA10复用成串口1功能不可用 驱动测试代码如下: main.c: #include "main.h" #include <stdio.h>void usart1_init(void) {GPIO_InitTypeDef GPIO_InitStruct…...
C语言之 结构体,枚举,联合
目录 1.结构体 1.1结构的基础知识 1.2结构的声明 1.3 特殊的声明 1.4 结构的自引用 1.5 结构体变量的定义和初始化 1.6 结构体内存对齐 1.7 修改默认对齐数 1.8 结构体传参 2. 位段 2.1 什么是位段 2.2位段的内存分配 2.3 位段的跨平台问题 3. 枚举 3.1 枚举类型…...
红米电脑硬盘剪切
Redmi R14 2023版固态硬盘剪切 工具准备操作结尾语 首先要说明,本文所说的操作不一定适合你的电脑,因为电子产品更新换代过快,你的硬盘不一定能剪切,在操作前一定要仔细观察硬盘的型号,是否为同款,我上了图…...
微信小程序在线预览PDF文件
需求:微信小程序在线预览PDF合同文件,加载完成后强制阅读10秒才可点击同意按钮 H5代码: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" cont…...
Android 工厂模式增加Type-A功能测试
Android 工厂模式增加Type-A功能测试 收到客户需求想要增加Type-A测试项来验证Type-A功能,具体功能实现参照如下: /vendor/freeme/packages/apps/FreemeFactoryTest/src/com/freeme/factory/usb/TypeAUSB.java package com.freeme.factory.usb;i…...
Web攻防06_sqlmap的使用
文章目录 参考链接: SQLMAP简介支持五种不同的注入模式 数据猜解-库表列数据权限操作引出权限:引出文件:引出命令(执行命令): 提交方法-POST&HEAD&JSONPost注入cookie注入注入请求头中(…...
C++模拟实现-----日期计算器(超详细解析,小白一看就会!)
目录 一、前言 二、日期类计算器 三、日期计算器的实现 🍎日期计算器各个接口的实现 🍐日期计算器的需求 🍉打印当前日期(并检查日期是否合理) 💦检查日期是否合理 💦日期类构造函数&#x…...
Oracle实现把B表某一字段更新到A表
1.使用SQL命令UPDATE语句。 2.使用MERGE语句。 3.使用TRIGGER触发器。 4.使用游标CURSOR和循环 使用游标和循环来将B表中的数据更新到A表中,从而实现了两个表数据的同步。例如下面的代码实现:...
CUMCM历年赛题汇总
题目来源: 全国大学生数学建模竞赛官网 注:题目和数据均可在官网下载 2021–2023年 年份题号题目2023A定日镜场的优化设计2023B多波束测线问题2023C蔬菜类商品的自动定价与补货决策2023D圈养湖羊的空间利用率2023E黄河水沙监测数据分析2022A波浪能最大…...
人间道-您到底做错了什么:正心径之您要逐渐去除外邪行为
过去的您或许在您自个身上付出,投入了巨大,重大的人力,物力,财力等各方面的重重的成本,但是呢,收获却微小的稀罕,微少的可怜啊。甚至于一个错误,就把您完全陷入到万丈深渊里面去了&a…...
Spring Boot拓展XML格式的请求和响应
在我们开发过程中,我们经常使用的参数绝大多少事HTML和JSON格式的请求和响应处理,但是我们在实际开发过程中,我们可能经历一些,比如对于XML格式的请求,我们在后端应该如何接收,并且如何将XML格式的参数变成…...
0045【Edabit ★☆☆☆☆☆】【字符数转整型】Return a String as an Integer
0045【Edabit ★☆☆☆☆☆】【字符数转整型】Return a String as an Integer language_fundamentals numbers strings Instructions Create a function that takes a string and returns it as an integer. Examples stringInt("6") // 6 stringInt("1000&q…...
数据库MySQL(六):事务
事务 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。 MySQL中默认事务是自动提交的,当执行完一条DML语句时…...
比较浮点数时,我被绊倒了
📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不是…...
JVM进阶(1)
一)JVM是如何运行的? 1)在程序运行前先将JAVA代码转化成字节码文件也就是class文件,JVM需要通过类加载器将字节码以一定的方式加载到JVM的内存运行时数据区,将类的信息打包分块填充在运行时数据区; 2)但是字节码文件是JVM的一套指…...
【AICFD案例操作】汽车外气动分析
AICFD是由天洑软件自主研发的通用智能热流体仿真软件,用于高效解决能源动力、船舶海洋、电子设备和车辆运载等领域复杂的流动和传热问题。软件涵盖了从建模、仿真到结果处理完整仿真分析流程,帮助工业企业建立设计、仿真和优化相结合的一体化流程&#x…...
Hadoop 请求数据长度 Requested Data length 超过配置的最大值
一、问题 现象 Spark 任务速度变慢,也不失败。 DataNode 内存足够 CPU 负载不高 GC 时间也不长。 查看 DataNode 日志,发现有些日志出现很多 Netty RPC 超时。超时的 destination 是一个 NameNode 节点,然后查看 NameNode 节点的日志&…...
搜索与图论:染色法判定二分图
将所有点分成两个集合,使得所有边只出现在集合之间,就是二分图 二分图:一定不含有奇数个点数的环;可能包含长度为偶数的环, 不一定是连通图 染色可以使用1和2区分不同颜色,用0表示未染色 遍历所有点&…...
磁场设备主要有哪些
磁学是物理学最古老的研究领域之一,目前仍然充满了生机活力。对于磁性物理的科学研究、磁性材料相关的探索来说,磁场设备必不可少,因为在外加磁场的作用下,样品会表现出特殊的物理性质,并带来了巨大的应用前景…...
【wespeaker】模型ECAPA_TDNN介绍
本次主要介绍开源项目wespeaker模型介绍 1. 模型超参数 model_args: feat_dim: 80 embed_dim: 192 pooling_func: “ASTP” projection_args: project_type: “softmax” # add_margin, arc_margin, sphere, softmax scale: 32.0 easy_margin: False 2. 模型结构 2.1 Layer…...
OpenClaw效率对比:Qwen2.5-VL-7B与传统OCR工具在文档处理中的表现
OpenClaw效率对比:Qwen2.5-VL-7B与传统OCR工具在文档处理中的表现 1. 测试背景与动机 最近在整理公司历史项目文档时,遇到了一个棘手的问题:大量扫描版PDF和图片格式的技术文档需要数字化处理。这些文档包含代码片段、手写注释和复杂表格&a…...
OpenClaw云端体验指南:无需本地安装快速测试Phi-3-vision-128k-instruct
OpenClaw云端体验指南:无需本地安装快速测试Phi-3-vision-128k-instruct 1. 为什么选择云端体验OpenClaw 作为一个长期折腾本地AI部署的技术爱好者,我完全理解那种"想先试试再决定是否投入"的心态。去年尝试在MacBook Pro上部署Llama 2时&am…...
网络基础必问:简单谈谈你对DNS的理解?原理+流程图+通俗讲解
网络基础必问:简单谈谈你对DNS的理解?原理流程图通俗讲解一、前言二、DNS 是什么?(一句话核心)三、为什么需要 DNS?四、DNS 完整工作流程图(最清晰)五、DNS 解析步骤(简单…...
智慧校园系统怎么选?看懂这 5 个核心功能再决定不迟
✅作者简介:合肥自友科技 📌核心产品:智慧校园系统(包括教工管理、学工管理、教务管理、考务管理、后勤管理、德育管理、资产管理、公寓管理、实习管理、就业管理、离校管理、科研平台、档案管理、学生平台等26个子平台) 。公司所有人员均有多…...
Kubernetes 部署 Spring Boot 应用:从入门到生产实践
Kubernetes 部署 Spring Boot 应用:从入门到生产实践 别叫我大神,叫我 Alex 就好。 一、引言 大家好,我是 Alex。Kubernetes 已经成为云原生应用部署的事实标准,而 Spring Boot 是 Java 微服务开发的首选框架。今天,我…...
SMU Debug Tool完全指南:AMD Ryzen硬件调试的终极解决方案
SMU Debug Tool完全指南:AMD Ryzen硬件调试的终极解决方案 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https:…...
Atlas 800I A2实战:5小时搞定DeepSeek V3 W4A8量化全流程(含显存优化技巧)
Atlas 800I A2实战:5小时搞定DeepSeek V3 W4A8量化全流程(含显存优化技巧) 在AI模型部署领域,量化技术正成为突破硬件限制的关键手段。当我们面对Atlas 800I A2这样的高性能服务器时,如何充分发挥其64GB显存优势&#…...
2025Reddit养号实战:3步打造高Karma账号矩阵
1. Reddit养号基础:为什么Karma值如此重要? 如果你刚接触Reddit,可能会对这个平台的"Karma系统"感到困惑。简单来说,Karma就像你在Reddit社区里的信用积分,它决定了你的发言权和影响力。我刚开始运营Reddit账…...
Dual-Loop Adaptive AI System Whitepaper(DLAAS)双环自适应AI系统正式命名白皮书
Dual-Loop Adaptive AI System Whitepaper(DLAAS)双环自适应AI系统—— 基于六元结构(TSPR-WEB-LLM-HIC-A-F)的生成式AI决策操作系统版权与所有权声明本技术系统的全部知识产权归以下主体独家所有:拓世网络技术开发室&…...
如何用QtScrcpy突破手机操控局限?三大创新方案让多场景效率提升300%
如何用QtScrcpy突破手机操控局限?三大创新方案让多场景效率提升300% 【免费下载链接】QtScrcpy Android real-time display control software 项目地址: https://gitcode.com/GitHub_Trending/qt/QtScrcpy 手机屏幕太小导致操作失误?多设备管理切…...
