STM32-串口通信(串口的接收和发送)

2023-05-16

文章目录

  • STM32的串口通信
  • 一、STM32里的串口通信
  • 二、串口的发送和接收
    • 串口发送
    • 串口接收
  • 三、串口在STM32中的配置
  • 四、串口接收的两种实现方式
    • 1. 需要更改的地方
    • 2. 查询RXNE标志位
    • 3. 使用中断
  • 总结


STM32的串口通信

本文在于记录自己的学习过程中遇到的问题和总结,各种情况下串口通信在STM32的实际使用方面占有很大的比重,本文主要对串口通信做一个简要的总结。


一、STM32里的串口通信

在STM32里,串口通信是USART,STM32可以通过串口和其他设备进行传输并行数据,是全双工异步时钟控制,设备之间是点对点的传输。对应的STM32引脚分别是RX和TX端。STM32的串口资源有USART1、USART2、USART3.

串口的几个重要的参数:

  • 波特率,串口通信的速率
  • 空闲,一般为高电平
  • 起始位,标志一个数据帧的开始,固定为低电平。当数据开始发送时,产生一个下降沿。(空闲–>起始位)
  • 数据位,发送数据帧,1为高电平,0为低电平。低位先行。
    比如 发送数据帧0x0F 在数据帧里就是低位线性 即 1111 0000
  • 校验位,用于数据验证,根据数据位的计算得来。有奇校验,偶校验和无校验。
  • 停止位,用于数据的间隔,固定为高电平。数据帧发送完成后,产生一个上升沿。(数据传输–>停止位)

下方就是一个字节数据的传输过程,从图中可以看出,串口发送的数据一般都是以数据帧的形式进行传输,每个数据帧都由起始位,数据位,停止位组成, 且停止位可变。
在这里插入图片描述


二、串口的发送和接收

USART是STM32内部集成的硬件外设,可以根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可以自动接收RX引脚的数据帧时序,拼接成一个字节数据,存放在数据寄存器里。

当配置好USART的电路之后,直接读取数据寄存器,就可以自动发送数据和接收数据了。在发送和接收的模块有4个重要的寄存器

  • 发送数据寄存器TDR
  • 发送移位寄存器,把一个字节的数据一位一位的移出去
  • 接收数据寄存器RDR
  • 接收移位寄存器,把一个字节的数据

下方为串口的发送和接收图解:

在这里插入图片描述


串口发送

在配置串口的各个参数时,可以选择发送数据帧的数据位的大小,可选8位或9位。

串口发送数据实际上就是对发送数据寄存器TDR进行写操作

1. 当串口发送数据时,会检测发送移位寄存器是不是有数据正在移位,如果没有移位,那么这个数据就会立刻转移到发送移位寄存器里。准备发送。

2. 当数据移动到移位寄存器时,会产生一个TXE发送寄存器空标志位,该位描述如下。当TXE被置1,那么就可以在TDR写入下一个数据了。即发送下一个数据。

在这里插入图片描述

3. 发送移位寄存器在发送器控制的控制下,向右移位,一位一位的把数据传输到TX引脚。
在这里插入图片描述

4. 数据移位完成后,新的数据就会再次从TDR转移到发送移位寄存器里来,依次重复1-3的过程。通过读取TXE标志位来判断是否发送下一个数据。


串口接收

  1. 数据从RX引脚通向接收移位寄存器,在接收控制的控制下,一位一位的读取RX的电平,把第一位放在最高位,然后右移,移位八次之后就可以接收一个字节了。
  2. 当一个字节数据移位完成之后,这一个字节的数据就会整体的移到接收数据寄存器RDR里来。
  3. 在转移时会置RXNE接收标志位,即RDR寄存器非空,下方为该位的描述。当被置1后,就说明数据可以被读出
    在这里插入图片描述
    下图即为串口接收的工作流程

在这里插入图片描述


三、串口在STM32中的配置

首先要明确几点:使用STM32串口外设中的哪一个?串口发送或者接收数据?串口相关的参数配置?发送或接收是否使用到中断?

下方为串口发送的配置。

1. RCC开启USART、串口TX/RX所对应的GPIO口

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);  //开启USART2的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);   //开启GPIOA的时钟

2. 初始化GPIO口
这里注意哈,根据自己的需求来配置GPIO口,发送和接收是都需要还是只需要其中一个。然后对应的根据引脚定义表来初始化对应的GPIO口。

USART2对应的引脚
在这里插入图片描述

USART1对应的引脚
在这里插入图片描述

这里根据手册来看,RX引脚模式配置成浮空输入或者上拉输入。TX引脚模式配置成复用推挽输出。

**比如我这里只初始化TX发送端**
//TX端
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;  //复用推挽输出
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;   //USART2对应的TX端为GPIOA2
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;  //50MhZ
    GPIO_Init(GPIOA,&GPIO_InitStructure);

3. 串口初始化
注意哈,USART_Init()这个函数,是用来配置串口的相关参数的。

  • USART_BaudRate 串口通信使用的波特率 一般是9600或者是115200,这里我们给9600
  • USART_HardwareFlowControl 是否选择硬件流触发,一般这个我们也不选,所以选择无硬件流触发。
  • USART_Mode 这个参数要注意了哈,串口的模式,发送模式还是接收模式,还是两者都有
  • USART_Parity 校验位,可以选择奇偶校验和不校验。没有需求就直接无校验
  • USART_StopBits 停止位 有1、0.5、2位,我们这里选1位停止位
  • USART_WordLength 数据位 有8位和9位可以选择
 //串口初始化
	USART_InitTypeDef USART_InitStruct;
	USART_StructInit(&USART_InitStruct);  //初始默认值
	USART_InitStruct.USART_BaudRate=9600;
	USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;   //不使用硬件流触发
	USART_InitStruct.USART_Mode=USART_Mode_Tx;   			//TX 发送模式
	USART_InitStruct.USART_Parity=USART_Parity_No;   		//不选择校验
	USART_InitStruct.USART_StopBits=USART_StopBits_1;  		//停止位1位
	USART_InitStruct.USART_WordLength=USART_WordLength_8b;	//数据位8位
	USART_Init(USART2,&USART_InitStruct);

4. 串口使能

//串口使能
   USART_Cmd(USART2,ENABLE);

5. 串口发送数据
注意哈,我们要判断TXE标志位的状态。0,数据还没有被转移到移位寄存器;1,数据已经被转移到移位寄存器。当TXE标志位为1时,就说明可以发送下一个数据了。详细过程可看上面串口发送的解释。

void Serial_SendByte(uint16_t Byte)
{
	USART_SendData(USART2,Byte);
	//0 表示数据还未转移到移位寄存器 循环等待 1 数据已经被转移到了移位寄存器可以发送数据
	while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);  //不需要手动清零 再次写入TDR时会自动清零	
}

经过上述五步的配置,单片机就可以通过串口发送数据了。

下方为发送数据图例,STM32向串口发送0x16数据
在这里插入图片描述


四、串口接收的两种实现方式

上方是发送数据的例子,那么串口接收又该如何配置,又要在串口发送的例子上做哪些更改呢?

这里我们可以通过查询或者中断的方式来进行接收数据的两种方式。

  • 查询方式就是通过不断的查询RXNE标志位,通过判断RXNE位的状态来确定数据是否接收。
  • 中断方式就是通过配置接收输出控制通道,配置NVIC,在中断服务子函数里进行数据的接收。

1. 需要更改的地方

既然我们要实现串口的接收,那么就要配置串口RX引脚,在串口模式中添加USART_Mode_RX模式。

  • 初始化RX引脚
//RX端
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;  //上拉输入
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;  //50MhZ
    GPIO_Init(GPIOA,&GPIO_InitStructure);
  • 添加串口模式
USART_InitStruct.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;   			//TX 发送模式  RX 接收模式

2. 查询RXNE标志位

这里我们还是来看一看RXNE标志位的描述

在这里插入图片描述
上图描述,为0时数据没有收到,为1时收到了数据,数据可以从RDR里读出

所以在主程序里不断读取RXNE标志位,如果为1,表示数据可以读出

uint8_t RX_Data;
int main()
{ 
    Serial_Init();
    Serial_SendByte(0x16);
    while(1)
    {
        if(USART_GetFlagStatus(USART2,USART_FLAG_RXNE)==SET)   //0 循环等待 1 可以接收数据
        {
            RX_Data=USART_ReceiveData(USART2);           
			Serial_SendByte(RX_Data);
        }
    }
}

下图为程序现象:pc向单片机发送数据0x15,单片机接收数据0x15,并且把接收到的数据作为数据发送到pc,在pc上显示0x15。
在这里插入图片描述

3. 使用中断

  • 通过配置串口的接收作为中断源,开启中断输出控制,配置NVIC。开启中断通道。
//开启中断输出控制
	USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
	
	//配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel=USART2_IRQn;   //选择USART2的中断通道
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;		//中断使能
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStruct);
  • 中断服务子函数
    中断服务子函数写好后,就可以在中断里读取接收到的数据了。
    当接收到数据后,触发接收中断,主程序暂停执行。接收完数据后主程序回复执行。当接收到数据时,就触发中断。
void USART2_IRQHandler(void)
{
	if(USART_GetITStatus(USART2,USART_IT_RXNE)==SET)   //RXNE 标志位为1 表示可以接收数据
	{
		RX_Data=USART_ReceiveData(USART2);
		Flag=1;
		USART_ClearITPendingBit(USART2,USART_IT_RXNE);  //清除RXNE标志位
	}
}
  • 主程序测试
uint8_t RX_Data;
uint8_t Flag;

int main()
{
    Serial_Init();
    Serial_SendByte(0x16);


    while(1)
    {
        if(Flag==1)
        {
            Serial_SendByte(RX_Data);
        }
    }
}

void USART2_IRQHandler(void)
{
    if(USART_GetITStatus(USART2,USART_IT_RXNE)==SET)   //RXNE 标志位为1 表示可以接收数据
    {
        RX_Data=USART_ReceiveData(USART2);
        Flag=1;
        USART_ClearITPendingBit(USART2,USART_IT_RXNE);  //清除RXNE标志位
    }
}

下图为程序现象:可以看到,串口确实收到了数据,只是我把接收到的数据0xFE放在了while循环里,这说明数据接收是成功的,使用中断是可行的。
在这里插入图片描述


总结

到这里,就大致总结了串口的发送和接收。

串口的配置,使用查询或者中断来接收数据。

串口的使用会很常用到,所以在这里对串口做一个总结,也算是对之前知识的一个回顾和总结,加强印象。

如果有什么写的不对的地方,欢迎指正!

加油加油!

听不懂就多看两遍,认真听,慢慢琢磨,多看几遍,一定可以学会!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32-串口通信(串口的接收和发送) 的相关文章

  • 处理器指令周期执行时间

    我的猜测是 no operation 内在 ARM 指令应花费 1 168 MHz 来执行 前提是每个NOP在一个时钟周期内执行 我想通过文档验证这一点 有关处理器指令周期执行时间的信息是否有标准位置 我试图确定 STM32f407IGh6
  • 如何更改闪存的起始地址?

    我正在使用 STM32F746ZG 和 FreeRTOS Flash的起始地址是0x08000000 但我想把它改成0x08040000 我通过谷歌搜索了这个问题 但没有找到解决方案 我更改了链接器脚本 如下所示 MEMORY RAM xr
  • HAL库STM32常用外设教程(二)—— GPIO输入\输出

    HAL库STM32常用外设教程 二 GPIO输入 输出 文章目录 HAL库STM32常用外设教程 二 GPIO输入 输出 前言 一 GPIO功能概述 二 GPIO的HAl库驱动 三 GPIO使用示例 1 示例功能 四 代码讲解 五 总结
  • STM32F103

    提示 来源正点原子 参考STM32F103 战舰开发指南V1 3PDF资料 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 开发环境硬件普中科技 接线图在g
  • 物联网网关

    物联网网关是 连接物联网设备和互联网的重要桥梁 它负责将物联网设备采集到的数据进行处理 存储和转发 使其能够与云端或其它设备进行通信 物联网网关的作用是实现物联网设备与云端的无缝连接和数据交互 物联网网关功能 数据采集 物联网网关可以从物联
  • HAL库学习

    CMSIS简介 CMSIS Cortex Microcontroller Software Interface Standard 微控制器软件接口标准 由ARM和其合作的芯片厂商 ST NXP 软件工具厂商 KEIL IAR 共同制定的标准
  • 毕业设计 江科大STM32的智能温室控制蓝牙声光报警APP系统设计

    基于STM32的智能温室控制蓝牙声光报警APP系统设计 1 项目简介 1 1 系统构成 1 2 系统功能 2 部分电路设计 2 1 stm32f103c8t6单片机最小系统电路设计 2 2 LCD1602液晶显示电路设计 2 2 风
  • [屏驱相关]【SWM166-SPI-Y1.28C1测评】+ 有点惊艳的开箱

    耳闻华芯微特许久了 看到论坛得评测活动赶紧上了末班车 毕竟对有屏幕得板子也是很喜欢得 京东快递小哥客客气气 微笑着把快递给了我 好评 直接拆了包 在此之前没看过视频号 所以这个圆盘盘得模具还是有点惊喜的 正面照如下 开机有灯光秀 还有动画
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 跟着野火学FreeRTOS:第一段(任务定义,切换以及临界段)

    在裸机系统中 系统的主体就是 C P U CPU CP U 按照预先设定的程序逻辑在 m a i n
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i
  • 毕设开题分享 单片机智能教室系统(智能照明+人数统计)

    1 简介 Hi 大家好 今天向大家介绍一个学长做的单片机项目 单片机智能教室系统 智能照明 人数统计 大家可用于 课程设计 或 毕业设计 项目分享 https gitee com feifei1122 simulation project
  • Freertos低功耗管理

    空闲任务中的低功耗Tickless处理 在整个系统运行得过程中 其中大部分时间都是在执行空闲任务的 空闲任务之所以执行 因为在系统中的其他任务处于阻塞或者被挂起时才会执行 因此可以将空闲任务的执行时间转换成低功耗模式 在其他任务解除阻塞而准
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • 核心耦合内存在 STM32F4xx 上可执行吗?

    尝试从 STM32F429s CCM 运行代码 但每当我命中 CCM 中的第一条指令时 我总是会遇到硬故障 并且 IBUSERR 标志被设置 该指令有效且一致 STM32F4xx 是否可能不允许从 CCM 执行 数据访问效果良好 alios
  • 嵌入式 C++11 代码 — 我需要 volatile 吗?

    采用 Cortex M3 MCU STM32F1 的嵌入式设备 它具有嵌入式闪存 64K MCU固件可以在运行时重新编程闪存扇区 这是由闪存控制器 FMC 寄存器完成的 所以它不像a b那么简单 FMC 获取缓冲区指针并将数据刻录到某个闪存
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能
  • stm32l0: 执行MI命令失败。使用 vFlashErase 数据包擦除闪存时出错

    我正在使用 Nucleo STM32L031 和 AC6 STM32 工作台 eclipse 我编写应用程序并进入调试模式 一切正常 直到我在应用程序中添加另一个功能 我注意到当我删除 评论 新函数 软件可以再次进入调试模式 但是当我添加

随机推荐

  • 2022研究生数学建模B题思路

    子问题1 xff1a 排样优化问题 要求建立混合整数规划模型 xff0c 在满足生产订单需求和相关约束条件下 xff0c 尽可能减少板材用量 约束 1 在相同栈 stack xff09 里的产品项 item xff09 的宽度 xff08
  • 找到并标记Mesh顶点

    1 在Unity 3D中新建一个物体 本文以Cube为例 2 创建一个C 脚本 命名为MeshTest 3 在脚本中写入程序 在打开的脚本 MeshTest 上编写代码 xff0c 首先获取 MeshFilter 组件 xff0c 然后获取
  • win11 命令 wmic:无效的指令 解决办法

    我想你肯定看到过让你修改环境变量的方法 但是 xff0c 如果你的电脑就根本没有装wmic xff0c 再怎么修改环境变量也是徒劳 我们打开设置 xff1a Win 43 I 点击应用 选择 可选功能 添加可选功能 搜索wmic xff0c
  • 【STM32】GPIO_InitTypeDef GPIO_InitStructure;语句的理解

    这句话声明一个结构体 xff0c 名字是GPIO InitStructure xff0c 结构体原型由GPIO InitTypeDef 确定 xff0c 在stm32中用来初始化GPIO 设置完GPIO InitStructure里面的内容
  • 如何在VScode上运行C语言

    如何在VS code上运行C语言 安装VS code 下载MinGW w64 xff1b 查验是否成功 我在VS code上尝试运行C语言后 xff0c 想和大家分享一下经验 安装VS code 下载MinGW w64 xff1b 查验是否
  • Node.js 如何实现OCR文字识别

    Node js 如何实现OCR文字识别 OCR Optical Character Recognition 是指用光学技术识别文字图像的技术 随着全新的技术出现 xff0c OCR 技术已经发展成为一种非常先进的技术 xff0c 可以从图片
  • Jetson nano烧录与简介

    Jetson nano 烧录教程 文章目录 Jetson nano 烧录教程 Jetson nano 简介1 Jetson Nano 接口介绍2 盒内包含3 不包含的物品 xff08 额外购入 xff09 4 Jetson nano的三种供
  • 51单片机-定时器(简易时钟的实现)

    文章目录 前言一 定时器的功能以及定时器的结构定时器的功能定时器的结构 二 定时器的控制工作模式寄存器TMOD控制寄存器TCON写代码来初始化定时器 三 定时器引发中断简易时钟主程序main c延时函数Delay c控制LCD162模块LC
  • 用于评估婴儿认知发展的IMU内嵌式玩具

    0 5岁是神经发育的敏感时期 xff0c 对身心健康至关重要的EF xff08 执行功能 Executive functions xff09 会在这个时期出现 在现代临床和研究实践中 xff0c 编码员通过手动标记视频中婴儿在使用玩具或社交
  • yolo+ocr集装箱字符识别(pytorch版本)

    前言 这个是我们 的大创项目 当我们拿到一份数据集 xff0c 首先就是要对整个项目有个较为清晰的认识 xff0c 整体的思路是什么 xff0c 难点在哪 xff0c 怎么部署和实现 1 整体的思路 xff1a 先通过目标检测网络 xff0
  • ROS话题通信实现发布接收以及vscode编译配置(五)C++版本

    在ROS中每一个功能点都是一个单独的进程 xff0c 每一个进程都是独立运行的 ROS是进程 xff08 也称为Nodes xff09 的分布式框架 因为这些进程甚至还可分布于不同主机 xff0c 不同主机协同工作 xff0c 从而分散计算
  • CMakeList

    目录 1 简介 2 常用命令 2 1 指定 cmake 的最小版本 2 2 设置项目名称 2 3 设置编译类型 2 4 指定编译包含的源文件 2 4 1 明确指定包含哪些源文件 2 4 2 搜索所有的 cpp 文件 2 4 3自定义搜索规则
  • 多旋翼飞行器设计与控制(二)—— 基本组成

    多旋翼飞行器设计与控制 xff08 二 xff09 基本组成 一 机架 1 机身 指标参数 xff1a 重量 xff1a 尽可能轻轴距 xff1a 外圈电机组成圆的直径材料 xff1a 冲碳纤维就完了布局 xff1a 2 起落架 作用 xf
  • 多旋翼飞行器设计与控制(六)—— 动态模型和参数测量

    多旋翼飞行器设计与控制 xff08 六 xff09 动态模型和参数测量 一 多旋翼控制模型 刚体运动学模型 跟质量与受力无关 xff0c 只研究位置 速度 姿态 角速度等参量 xff0c 常以质点为模型 刚体动力学模型 它与一般刚体动力学模
  • 多旋翼飞行器设计与控制(七)—— 传感器标定和测量模型

    多旋翼飞行器设计与控制 xff08 七 xff09 传感器标定和测量模型 一 三轴加速度计 三轴加速度计是一种惯性传感器 xff0c 能够测量物体的比力 xff0c 即去掉重力后的整体加速度或者单位质量上作用的非引力 当加速度计保持静止时
  • 【STM32】stm32通过地址操作寄存器

    stm32通过地址操作寄存器 0x01 stm32数据类型所占字节数0x02 如何查看寄存器地址 xff08 基地址 43 偏移地址 xff09 0x03 操作寄存器地址控制LED闪烁 xff08 代码 xff09 0x04 通过定义结构体
  • ARM裸机开发——启用SDRAM的按键中断控制灯实验

    写在前面 本文承接前文嵌入式系统学习 嵌入式系统 Linux环境搭建和LED灯闪烁实验 以S3C2440A作为开发平台 xff0c 以Linux中ARM Linux gcc交叉编译器作为编译环境进行学习 xff0c 由于本课程为单片机基础的
  • 二维vector

    span class token macro property span class token directive keyword include span span class token string lt iostream gt s
  • 13.request-session,验证码

    使用session使得请求变成一个对象 注意登录页面隐藏的参数 爬取古诗文登录页面 span class token keyword import span requests span class token keyword from sp
  • STM32-串口通信(串口的接收和发送)

    文章目录 STM32的串口通信一 STM32里的串口通信二 串口的发送和接收串口发送串口接收 三 串口在STM32中的配置四 串口接收的两种实现方式1 需要更改的地方2 查询RXNE标志位3 使用中断 总结 STM32的串口通信 本文在于记