通用异步收发器 UART

通用异步收发器:Universal Asynchronous Receiver/Transmitter(UART),这就是 UART 的中文名称(不是叫串口吗?以前一直这么叫它)。

同步 vs 异步:双方靠什么对齐 现在这一位

同步:有一根专门的时钟线(或时钟藏在编码里,比如曼彻斯特编码,通过电平的跳变来告诉接收端如何采样)。发送端每跳一次时钟,接收端就采一位,不必事先死记波特率。

异步:没有时钟线。双方事先约定波特率(例如 115200),靠起始位对齐,然后按时间自己数位。【Asynchronous(异步)】

全双工 vs 半双工:双边收、发完全 可以并行,互不影响

全双工(Full Duplex):两条独立数据通路,可以同时对发。

就像一条路来、回各一条车道。你往前开,对面照样开,互不堵。UART 的 TX、RX 就是这样。

半双工(Half Duplex):共用一条数据通路,同一时刻只能一个方向。

就像一条路中间只有一条车道。同一时刻只允许一个方向的车。对面要过来,你得先驶出这段。

还有一种更为严格的:单工:永远只一个方向,如遥控器、单向传感器输出。

工业标准 NRZ 串行数据格式:Non-Return-to-Zero(不归零)

与之相反的RZ:Return-to-Zero(归零),一个典型的例子就是WS2812

可以看出来,下面是WS2812的编码,无论是0码还是1码,中间会都回到零点,这就是RZ

而串口呢,我们可以看到,它的每一位在传输的过程中,是不需要回到零点的,这就是NRZ

数据传输长度:8 或 9 位

UART可以配置自己的数据传输长度。【这里我用了STM32F10x的手册内的内容】

可以看到,UART是可以配置为传输8位 or 9位的数据的

一次完整的UART数据,其数据格式为:起始位 + 数据帧 + 停止位,其中:数据帧的长度可以是 8位 或者 9位

那么停止位1位还是两位就跟容易了:他说明的是 停止位的数据长度是 1个bit 还是 2个bit

UART中,1个bit的数据长度就是:1 / 波特率

从图上可以看出:这里停止位是一个1bit,长度是26.16us,我这里配置的波特率是38400

1 / 26.16us = 38,226.2,符合设置的波特率

数据从低位开始发送/接收:低位先发、低位先收

这个是UART默认的发送与接收方式,因为串行数据一次只能走一位,必须约定从哪一头开始(不然不是乱了么)

从上面的图中可以看出,依次阅读每一位的bit,分别是:01010101

由于UART低位先发送,所以接收到的分别是【第0位】【第1位】【第2位】【第3位】【第4位】【第5位】【第6位】【第7位】

所以接收到的数据应该是:1010 1010 也就是 0xAA

发送器和接收器可单独使能:这个就是字面意思,你可以单独开 RX 或者 TX ,换句话说如果你没有发送的需求,你可以不开 RX ,这样可以省去一个IO口

支持 UART 接口 TX 开漏输出:这个适合很多场景啦

1、和一个VCC不同的芯片,发送消息给他【单向的,共地,外部加上拉电阻】

2、单线半双工:TX/RX 共用一根线。你在发时可以拉低;你不发时必须松开,对方才能把这根线拉低,所以单线 UART 几乎总是 开漏 + 上拉。【如果是推挽:空闲的时候你高电平,对面给你发起始位,拉低,直接短路了;就算中间加了电阻,整个线路也不会正常拉低的】

3、还有很多... 如果场合需要开漏,就可以开

发送 FIFO 为空中断、接收 FIFO 为非空中断

首先,FIFO:First In, First Out 先进先出,与之相对的 LIFO(Last In, First Out,后进先出)

前者,典型的数据结构就是:队列 FIFO

后者,典型的数据结构就是:堆栈 LIFO

这里指的就是 发送的硬件队列 / 接收的硬件队列

空中断:就是队列空的i时候,会触发中断 ------ 代表发送完成,队列里没有待发字节了,可以继续塞

非空中断:就是队列不是空的的i时候,会触发中断 ------ 代表有消息来了,已收队列有数据了,赶紧把字节读走,处理或放进自己的缓冲区

这个是代表着两种不同的数据处理逻辑

接收状态中断:帧错误、奇偶校验错误或接收溢出:

1、帧错误:一帧的结构对不上,最典型是:该出现停止位(高电平)的时候,线上却是低的。

2、奇偶校验错误:双方开了奇偶校验,收端按约定数完 0/1 个数,和发来的校验位对不上。

这里说一下奇偶校验是什么意思:奇偶校验是在数据位后面多加 1 位,让整段里 1 的个数变成偶数或奇数(校验位自己也会计入这个个数)。

【偶校验:让整段数据里面1的位数为偶数 / 奇校验:让整段数据里面1的位数为奇数】

3、接收溢出:新字节已经到了,旧字节还没被读走,硬件没地方放,旧数据或新数据被挤掉。

就是上面的 接收 FIFO,如果接收 FIFO已满,这时候又有新数据过来,那么就会导致接收有错误(旧数据被移除 / 新数据不进入?),说明处理跟不上了...

总之,这里就是如果出现一些异常的情况,会有中断来进行通知

让我们先看数据与地址总线这一路:

红色线:代表着配置UART外设寄存器,这里,我们会配置一些外设的参数:比如下下图中的配置流程:波特率、数据长度、奇偶校验位、停止位长度、运行模式,中断使能、外设使能等等...

绿色线:代表着向 TX-FIFO 发送队列中,传送待发送的数据

蓝色线:代表着从 RX-FIFO 接收队列中,读取已经收到的数据

红色线中的一些配置,一般芯片都会给你配置流程的

好,既然我们会传递数据给 TX FIFO / 从 RX FIFO 中读取,那么这个寄存器到底是长什么样子嘞:

下图就是 TX FIFO / RX FIFO,神奇的是,这俩用的是一个地址???难道只有一个吗?

其实在硬件层面,肯定是有两个的(甚至发送与接收电路肯定也是两套),但是早期的CPU为了省地址,就给这俩公用一个地址:UR0DAL

那怎么区分这两个硬件呢,当读这个寄存器的时候,调用的就会是 RX-FIFO;在写这个寄存器的时候,调用的就会使 TX-FIFO 【很精妙的设计,虽然...不是很好理解】

注:TX-FIFO 的深度为 1,RX-FIFO 的深度为 2

说明:TX-FIFO 只可以缓存一个字节的数据;而接收 RX-FIFO 可以缓存2个字节的数据

为什么bushiy

相关推荐
H_oRIZoN_1 小时前
Linux入门DAY45 IMX6ULL 裸机开发笔记:汇编点灯、C 语言点灯、GIC 中断梳理
linux·单片机·嵌入式硬件
离凌寒2 小时前
一、关于linux开发板上移植ubuntu根文件系统并配置桌面环境笔记记录
驱动开发·单片机
辰域电子2 小时前
STM32项目开源:实验室消防预警控制系统(代码 + 原理图 + 仿真)
stm32·单片机·嵌入式硬件·开源·proteus
老当益壮梁奶奶3 小时前
ARM汇编学习笔记(四):i.MX6ULL裸机开发:从汇编点灯到C语言BSP工程管理
c语言·arm开发·单片机·嵌入式硬件·51单片机
zjxtxdy17 小时前
SPI通信协议
笔记·单片机
朝发如雪20 小时前
快速掌握单片机基础(8)(内存映射与启动寻址方式)(编译工具链与构建流程)(C语言操作寄存器)
单片机
糖糖单片机设计21 小时前
基于STM32的电子密码锁设计与实现(矩阵键盘+防拆检测+GSM远程报警)
人工智能·stm32·单片机·嵌入式硬件
充哥单片机设计1 天前
【STM32开源项目】智能家电控制系统
stm32·单片机·嵌入式硬件·毕业设计·智能家电控制·家电控制
qq_401700411 天前
STM32 UART+DMA+IDLE 接收完整实现:从“能跑“到“不丢包“
单片机