理解USART真实收发过程

理解USART真实收发过程

  • [1.USART框图 及简化图](#1.USART框图 及简化图)
  • [2. 理解CPU读写TDR和RDR](#2. 理解CPU读写TDR和RDR)
    • [2.1 TDR和RDR](#2.1 TDR和RDR)
  • [3. STM32 USART 数据帧发送详细过程](#3. STM32 USART 数据帧发送详细过程)
    • [3.1 USART发送标志位介绍](#3.1 USART发送标志位介绍)
      • [3.11 从问题引入标志位](#3.11 从问题引入标志位)
  • [4. STM32 USART 接收详细过程](#4. STM32 USART 接收详细过程)
    • [4.1 USART接收标志位介绍](#4.1 USART接收标志位介绍)
    • [4.2 .阻塞模式](#4.2 .阻塞模式)

1.USART框图 及简化图

通过查找参考手册得到USART框图如下

  1. 图中 ① 标识区域是 USART 相关的管脚;
  2. 图中 ② 标识区域是 USART 波特率控制相关;
  3. 图中 ③ 标识区域是 USART 控制寄存器相关;
  4. 图中 ④ 标识区域是 USART 状态寄存器相关;
  5. 图中 ⑤ 标识区域是 USART 数据收、发相关核⼼功能框图;
  6. 图中 ⑥ 标识区域在 IrDA ( 红外模式 ) 和智能卡模式下才会使用

而我们目前只需要关系最核心的USART收发部分,即⑤ 标识的区域

简化成为

对与USART1 对应的就是APB2(高速外设总线).

2. 理解CPU读写TDR和RDR

复制代码
这两个寄存器属于 USART 模块内部,⽽其中 STM32F103ZET6 有 5 个串⼝模块,每⼀个都有⼀套独⽴的寄存器结构,我们以 USART1 为例。

查看数据手册得到

而我们知道片上外设的寄存器是直接被映射到CPU地址空间中的,被统一编址了。所以我们可以直接使用地址来访问TDR和RDR,从而对USART单元中的发送和接收寄存器进行数据读写,然后再有USART模块进行自主收发。

我们查询数据手册可以得到 寄存器映像图

如下

上图可知, USART1 的地址范围是: 0x4001 3800 - 0x4001 3BFF 。通过计算可得 这个空间大小为 1024字节也就是 1KB.

注意:虽然CPU内核只为 USART1 分配了 1KB 的地址空间,但实际使⽤的只有最开头的很少⼀部

分。后续的地址是保留的,访问它们可能产⽣不可预知的⾏为.

USART1 中,寄存器⼀共有 7 个,其中每⼀个寄存器都有⼀个偏移量地址,最终访问任何⼀个寄存器,访问⽅式都是:0x4001 3800 +寄存器偏移。(底层逻辑)

2.1 TDR和RDR

**得到USART_DR这个寄存器包含了 两个寄存器 TDR 和 RDR ,即分别用于发送数据 和 接收数据 **。

  1. 在物理上 ,USART_DR寄存器有两个,⼀个是TDR,⼀个是RDR分别让⽤⼾来发和收数据,
  2. 这两个寄存器被映射到了同⼀个物理地址,但是官⽅没有披露具体是怎么做到访问同⼀个地址,从⽽做到访问不同寄存器,我们可以可以推测通过操作类型(rw)来区分要访问哪⼀个寄存器。
    3.虽然 USART_DR 寄存器是 32 位的,但是实际使⽤的只有 9 位,因为 USART 可编程数据位最多是 9 位

3. STM32 USART 数据帧发送详细过程

为了⽅便表述,我们以实际中最常⽤的场景来进⾏阐述。

假设要发送的数据帧是: 1 起始位 + 8 数据位 + 1 校验位 + 1 停⽌位 = 11 位。

校验方式为odd ,即奇校验。

我们依旧以发送 0x55 为例,⼆进制是 0101 0101 ,采⽤奇校验,那么对应的数据位总共是9位:

0101 0101 + 1 位校验位。

❓ 注意:

校验位本⾝和数据的⼆进制中1的个数是有关的,需要和数据⼀起,发送给对⽅,那么校验位
就应该作为数据的⼀部分发送给接收⽅。

3.1 USART发送标志位介绍

当我们发送数据 0x55时,即 01 01 01 01,根据 奇校验 可得校验位 为1,得到 1 01 01 01 01

如图,数据从TDR被自主平移到发送移位寄存器 (又硬件电路完成)。然后在时钟的控制下,数据通过TX、而TX通过复用GPIO,从而输出 高低电平+。

复用GPIO的流程图

起始位的0和停止位的1 我们会理解为 低电平和 高电平,主要是和数据位区分,区分硬件电气特性和真实传递的数据。

3.11 从问题引入标志位

上述的发送数据过程,只是发送一个数据。可我们想想,是不是存在 这样的情况。

*即我们数据还在发送移位寄存器时,还没完全发送完。可此时我们又写入数据,或者发送数据寄存器已经有数据,而我们又向发送数据寄存器写入数据。这是就会导致数据覆盖和丢失。那么怎么解决呢?

我们怎么知道数据是否被及时传出去呢?

所以, USART 在⾃⼰的收发过程中,必须要提供⾃⼰收发状态的信息,这部分信息,叫做 USART 的状态寄存器( USART_SR :USART Status Register),可以预⾔,该寄存器内部,⼀定有标志位来表明
⽤⼾是否可以写⼊ TDR 的寄存器

USART 发送状态信息,由这 10 个标志位标识。对于发送数据的情况。我们关系 位 6和 位 7。

TXE : 表明如果 TXE是1,则TDR为空,如果TXE为0,则 TDR不为空。

TC:表明发送移位寄存器操作完成,如果TC为 1,发送操作未完成,则为 0;

那么什么情况表示用户把数据都发送完毕了呢?

当TXE ==1 && TC == 1,这种情况就表示没有数据要发送了。

接下来演示发送多个数据的过程。

比如依次发送 0x0 , 0x FF, 0x 55

如图,为未开始发送数据时

TXE和TC都== 1

接下来写入 0x0

此时 TXE不为空 ,即TXE == 0,此时如果用户还想写数据,由于TXE== 0,所以不能写入,如果执意写入,就是用户的问题了。

紧接着,由于数据已经写入,要开始发送到发送移位寄存器了,所以发送还没完成,所以TC也为 0.

紧接着

当数据到发送移位寄存器中了之后(由硬件自动完成)TEX == 1;

对于用户的视角来看,TXE == 1,表明可以写入数据了,此时继续写入0x FF。如下

此时 TXE 和 TC 都为 0,表明TDR已经有数据了,如果我们还是执意写数据就会导致数据被覆盖,所以**我们可以检测TXE,知道 TXE == 1 ,再写入数据,这种方式就叫做阻塞式写入,**当0x0,被发送出去后,TX会被拉成高电平,等待下个数据按照帧格式发送。以此类推。

4. STM32 USART 接收详细过程

有了之前 USART 发送数据的所有详细过程,那么其实我们后续学习数据接收⼀定会容易很多。

所谓的数据帧,本质也全部都是 01 ⽐特位,只不过被 USART 模块包装或者解析,接收的时候,把数据帧中数据部分提供给 RDR ,发送的时候把 TDR 的数据,包装成为数据帧。

类比发送过程中的问题,我们知道接收也一定会存在标志位的引入

接下来简单介绍单个数据的接收过程,然后结合引入标志位讲解多个数据的接收过程

以 0x55 为例,二进制为 01 01 01 01,

站在发送⽅⻆度:

接收控制器 接收到 一个 低电平,根据约定好的帧格式,知道要准备接收数据了,

依次接收一个bit位,接收到 1 后整体 右移,继续接收0 ,然后整体右移,最后得到 1 01 01 01 01,第一位为校验位,然后再整体给RDR最后被CPU读取,这个数据就是我们发送的0x55.这样就完成了单次数据的接收。

4.1 USART接收标志位介绍

上述接收数据的流程,我们忽略了重要的一点,那就是从用户的角度,我们怎么知道 数据从接收移位寄存器成功的被USART模块的硬件电路 移到 了 RDR呢,我们用户·怎么知道什么时候可以读取数据呢,所以就引出来了标志位。

USART 需要有⽅式,能表⽰ RDR 寄存器的状态,类
似发送,接收的时候,也是状态寄存器 USART_SR 来标识接收状态,其中, == RXNE == 标志位就是完成
该项⼯作的。

RXNE:读数据寄存器非空 (Read data register not empty)

• 当 RDR 寄存器中没有数据的时候,RXNE标志位被设置为0

• 当 RDR 寄存器中有数据的时候, RXNE 标志位被设置为1

• RXNE: Read data register not empty

所以,当 USART 在接受数据期间,那么⽤⼾就应该⼀直检测 RXNE 标志位,只要该标志位⼀直是
0 ,那么⽤⼾就应该⼀直阻塞在检测的位置,直到 RXNE == 1 表⽰有数据了,才能读取

所以 总的读取流程如下

当没有数据读取时,RXNE == 0;

接着来数据,按照帧格式 接收

RDR接收数据成功,RXNE被置为1.这时数据才可以被用户读取。

4.2 .阻塞模式

如果使⽤阻塞模式进⾏数据接收,程序需要轮询判断如 下图 所⽰的①②③的 RXNE 标志,主要逻辑

如下:

  1. RXNE 标志被置 0 ,表⽰暂时没有数据,要求⽤⼾轮询检测该标志位,标志位为0,就有⼀直阻塞
    在这⾥。
  2. 收到数据, RXNE 标志被置 1 ,表⽰接收到 1 字节数据,⽤⼾将读到的数据,保存到⾃⼰定义内存区域,读取的时候,会⾃动触发清除 RXNE 标志 ,然后继续检测 RXNE ,等待接收下⼀个数
    据。
  3. 达到期望接收的数据个数或等待数据超时,退出本次阻塞模式接收流程。
相关推荐
MartinYeung51 小时前
[论文学习]潜伏代理:训练能够经受安全训练的欺骗性大语言模型深度分析
学习·安全·语言模型
撩得Android一次心动1 小时前
Kotlin 语言【知识点整理3】
java·开发语言·笔记·学习·kotlin
2601_966949651 小时前
如何利用 1 分钟 K 线在 14:50 精准捕捉尾盘异动?Python 量化实战:1 分钟 K 线 + 全市场扫描
开发语言·人工智能·python·量化·quantdash·量化数据源
CarIise1 小时前
JavaScript基础语法与DOM操作实战课堂笔记
开发语言·javascript·笔记
林森lsjs1 小时前
零基础吃透二叉树:定义、遍历与高频算法 —数据结构柒
java·开发语言·数据结构·算法·二叉树
天空'之城2 小时前
单片机基础核心知识点汇总(十九)
单片机·嵌入式硬件
LCG元2 小时前
STM32 FreeRTOS 多任务实战:信号量同步、互斥量保护与优先级反转排查
stm32·单片机·嵌入式硬件
国科安芯2 小时前
星载CANFD总线通信网络中抗辐射微控制器MCU的失效机理与容错设计研究
网络·人工智能·分布式·单片机·嵌入式硬件·架构·抗辐射加固
wind100322 小时前
Qt5Widgets.dll 缺失报错|游戏软件无法启动完整修复教程
开发语言·qt·游戏·电脑