当前课程知识点:ARM微控制器与嵌入式系统 > 第五章 ARM微控制器的各种外设 > 5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上) > 5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上)
各位同学大家好
我是清华大学工程物理系的曾鸣老师
欢迎大家继续回到我们ARM微控制器
与嵌入式系统的MOOC课堂
我们这个单元呢
继续学习通讯这样一类外设的知识
那么在上一个小节里头 我们非常迅速的
过了关于通讯的若干个基本的术语和知识
如果系统的去学习通讯这是远远不够的
但是在一门嵌入式课程的角度
我们现在就应该带着问题开始实际的操练起来
学习一类通讯外设 逐渐加深看看我们
对于这一类的概念是否真的理解了
所以我们要学的第一类的 通讯外设
是个非常经典 非常常用的外设 我们往往说
我们是不是把一个新拿到手的芯片
或者一个新拿到手的嵌入系统玩起来了
最简单的两个标志就是有没有点一个灯
有没有用UART做一个异步串行通讯
这两件事情做通了 我们往往就认为
噢已经基本会用它了 然后后面就一个
是滚雪球的学习 那么他这么基本 这么重要
我们来讲讲它是为什么 它的机理是什么
那么UART是一类典型的异步串行通讯
UART这个词是
Universal Asynchronous Receiver Transmitter
这样一个四个词的缩写
那么我们按照英语习惯经常会把它称为UART
那么翻译成中文就是通用异步的接收和发送装置
那么UART在很多很多的计算机和嵌入式的MCU
还有外设上都会有 那么我们学习它的时候
还会看到另外一个很有名的词叫做SCI
SCI是Serial Communication Interface的缩写
就是串行通讯接口或者界面 这样一个词的缩写
那么这两个词所代表的这样一类通讯
在本质上是完全兼容的 为什么出现这两个词呢
因为前一个UART这个词
主要是在计算机的诞生历史沿程当中
由Intel提出 而且他在他的所有的资料和芯片里
都这么称呼它 包括ARM也延用了这种称呼
而SCI呢主要是由摩托罗拉在历史上提出的
他们实际上是兼容的 这样一种称呼在摩托罗拉
后续的所有的微控制器 芯片产品
乃至freescale NXP里头经常会遇到
所以我们今天要学习的第一类
异步串行通讯的典型外设我们称为UART
大家知道它跟SCI是同一个东西
那么我们在学习过程当中会知道这一类外设
他会有若干个通讯的特征跟上一节课呼应
比如他是串行的 是异步的 是点对点的
是全双工的 是对等的 那么这些词我这么念过来
大家可能即使拼命的回忆上节课讲的
你也没有详细的概念 我们一点点往下过
来加深它究竟是怎么回事儿
那么这样一类异步串行通讯讲了他是一个什么词
大家还没有概念 我们举个例子
我在第一节课给你讲过 我们的同学
学完这门课以后会做一些应用设计
比如这样一个放射源的监控终端
那么这样一个终端做出来以后 它有很多功能
它可以通过粒子探测器知道有没有
我们肉眼看不见的射线信号 然后可以呢
跟计算机通讯来设置一些参数
把这些数据发给计算机 然后他可以读一个
运动传感器知道这个设备
所绑定的这样一个监控对象有没有被搬动过
最后呢 他可以通过通讯接口获得自己GPS信息
我在哪个位置 并且把位置
这个测到的物理数据 还有我有没有被搬动
这样一些信息整体打包成一个短信
或者通过以太网想办法给送出去
送给手机送给计算机 那么这样一个设备做下来
很多同学现在觉得我还不会做
曾老师你跟我讲这么久我才刚刚入门
我们看看通讯在里头起什么作用 我们会发现
我们这门课要学到的UART 这样一种
异步串行通讯 在这样一个设计里
完成了我们这样一个设备的MCU微控制器
与计算机之间的通讯接口 有了它
我们人可以跟这个微控制器进行一些通讯
来设置一些参数 了解一些测量值 那么此外呢
我们与手机的短信模块与GPS定位模块之间
都是采用的UART通讯 然后呢我们之后还会讲
他与这个加速度的运动传感器
是我们之后要学到的另外一类的通讯
是同步串行通讯 而这样一个UART与GPS模块
与手机的短信模块的通讯
就会体现为我们现在这样看到这两个字符串
比如说我们会从GPS模块
得到一串一串的GPS的串码 里头隐含了我们当前
是否完成了卫星定位 完成卫星定位以后
我们的经度纬度乃至时标信息是什么
然后从GSM模块通讯 我们可以通过AT指令集
指导这个GSM模块编辑和向任意一个手机号
发出一条短信 而它的内容
可以是我们所获得的这样一些数据
所以我会发现 如我们上节课所讲
通讯就是完成设备与人之间
设备与设备之间的信息的传递的手段
可以说没有通讯 我们这样一个小小的微控制器
能够发挥的功能就会大打折扣
那么我们现在要学的UART
这样一种异步的串行通讯
它究竟是怎么一种模式呢
很多同学会注意到我舍掉了很多特性
一直带着异步 串行两个词在讲 对
让我们抽象出来就这么一张图 我们是串行的
所以我们会把我们要发送的数据
不管是一个字节还是几个字节
大家可以想象是在一根线上
通过时间上零和一的变化 来从一端
发给另外一端 那么我们有两端
一方比如说是MCU 一方是设备或者两个MCU之间
要完成这样一个异步的串行通讯的时候
我们可能会用到两个引脚 一个是a发给b
一个是b发给a 彼此之间各有一个方向对吧
这么我们会发现用掉两个引脚
那么在任何电子学系统里头我们一定不要忘记的
一件事情是两个系统之间要用电平信号
来进行通讯 传递信息的时候他们一定不要忘了
还要共地对吧 所以我们实际上用掉了三个引脚
对于任何一端来讲就是一个发送一个接收
和一个接地 对于两方的连接来讲
就是你的发送接我的接收
我的接收接你的发送 这样子
形成了一个完整的通讯 那么大家会发现
我们另外一个重要的词是异步通讯
所以在上一节课我讲过这个概念
说是接收端没有从发送端获得一个时钟信号
而是大家按照一个约定好的速率
来进行发送和接收 那么我们对于这个概念
进行一个很简单的抽象 一个串行的通讯
显然是像下面这样在一根信号线上
以一定的时间宽度 大家注意横轴是时间
以一定时间宽度 切换出一个一个的
0或者1我们称为一个比特 一个比特的
将它发送出来 而且接收端呢按照约定好的时间
去看这些一个比特 一个比特0和1
从而获得这个数据 完成这样一个通讯 对吧
这是一个基本的概念
那么这样看上去非常的和谐呀
你有一个引脚给我发 我有一个引脚给你发
我们大家约定好一个速率 在各自时钟的驱动下
比如约定好一秒钟一个比特
你就一秒钟一切换呗 我就一秒钟一看呗
这样我就得到了这个数据 完成这样一个通讯
那他是这么简单吗 我们在这里会
从一个设计和问题的角度来看
异步串行通讯UART 他究竟是怎样一种格式
和为什么会变成这个格式 我们现在提示一下
比如说我们接收端和发送端
各有一个时钟的驱动 那么这个时钟的驱动
很有可能它不是严格的一致的
这个非常可以想象 任何两个表 任何两个钟
他都无法做到严格的同步 那么我们极端一点想
我们发送端和接收端约定了一个发送的时间速率
或时间间隔 假设它们之间彼此之间
有一个小小的10%的误差 比如说
你每次按一秒钟来发送一个比特的数据切换
我接受端因为时钟上的偏差 我的时钟频率
没有那么准 我有10%的偏差 我只有900个毫秒
来查看这个数据 这个时候出现什么问题呢
就会发现我看着看着是不是就看错位了
从接收端看到第十个时间单位的时候看过去
实际上看的是发送端第九个时间单位所发出来的数据
于是你会发现这个时候接收端
所读到的数据跟发送端本来想表征的数据
已经面目全非了
如果大家去系统的学习通讯原理
这个时候我们的通讯已经出现了错误
已经出现了失真 这是不能接受的
那有些同学会说 老师没有这么大的时钟误差吧
我们这还稍微懂一点 这个晶振的时钟误差
一般都是几百个ppm 百万分之一百
或者百万分之几十 万分之一那误差很小的
那是不是发送和接收端的时钟误差
足够小就可以了呢 其实你会发现
如果按这样一种模式走
这种误差会一直累积下去
总会有一个比特数据出错吧 那怎么办呢
这是一个值得大家思考一下的问题
也是我们UART这样一种通讯
为什么是今天我们看到这样一种格式的问题
那么UART的数据真正的数据帧
实际上是这样一张表所表达的
那么在通讯上并不是像我刚才高度抽象的
就是永无止境的一个比特一个比特的发送
实际上他采用了一种称为 Frame format
也就是数据帧的格式
以后大家很多时候会学到类似的概念
比如在USB 在以太网 我们的数据
往往会以一个帧一个帧的方式
在发送和接收端进行传递 每一个帧里
承载一个字节或者若干个字节的数据
而通过一些结构把它封装起来 形成一个Frame
也就是一个数据帧 在我们这个单元里
就是带着大家看清楚UART这样一种数据结构
和数据帧 那么这样一种数据结构 数据帧
有一个英文的名称叫 NRZ encoding也就是
NRZ编码 那么光说英文术语
大家会觉得非常高大上 翻译过来很Low很简单
NRZ就是not return zero不归零的编码方式
顾名思义不归零 那就是一直维持逻辑1
那么我们在这样一张图里会看到
我们会用这个高电平代表逻辑1
低电平代表逻辑0 在idle的状态
没有任何通讯的时候 这个引脚空闲的时候
应该是请让它保持在逻辑1的状态 不变
也就是高电平不变 而每当一笔通讯发起的时候
我们这个数据帧在它的最前面
有一个start bit起始位 在它的最后
应该至少有一个比特宽的STOP bit停止位
而起始位永远是逻辑0 停止位永远是逻辑1
所以如果我们忽略我们里头的内容
详细结构的规定的话 我们就会发现
这样一个起始位的逻辑0一定会引起
我们从idle空闲状态 一次由1向0的跳变
维持一个比特的宽度 对不对 大家看图
那么到一个通讯结束的时候 因为停止位的结束
所以不论我们最后通讯的比特是零还是一
他一定会回归到高电平 然后跟idle连起来
维持空闲状态的高电平一直下去
直到下一个字节的通讯开始
大家可以想想 下一个字节开始通讯的时候
一定又有一个起始位 于是又是一次
由1向0的跳变 维持一个比特的宽度
成为一个起始位 所以我们这个通讯
就构成了在一个引脚信号上的一个一个的数据帧
每个数据帧的起始都是在空闲状态的高电平
完成一次由高到低的跳变
维持一个比特的起始位 再发送剩下的比特
再到一个高电平的停止位为结束
这就是数据帧的结构 那么在这样一个
数据帧的结构里头 我们会发现
我们要发送的内容 比如说一个字节
或者说以后学习别的数据帧 若干个字节
它都会有一个概念 就是我一个比特
是一个时间单位 比如一个起始位一个比特宽
那么这样一个比特的宽度 我们把它的倒数
定义为通讯里头另外一个很重要的量称为波特率
那波特率这个词非常奇怪 为什么呢
因为它就是英语Baud rate的音译
那么波特率 是我们在这样一个通讯里头
每秒钟传递多少个比特 这样一种宽度来定义的
所以比方说我们让这样一个比特的宽度
都停留一秒钟 那换言之 一秒钟
就是这一个比特宽 那么波特率就是1bps对吧
bits per second 那换言之
如果我们的波特率是一千bps
也就意味着我们在这个通讯里
约定好的这个数据帧 刚才看到的每一个格子宽
就是一个毫秒 千分之一秒
那么定义了这样一个起始位 停止位
又定义了一个波特率 还有这样一个
数据帧的结构 大家想想是为什么呢
这个时候回忆一下刚才第一页
我们讲的那个问题 有了这样一种数据帧的结构
在一个平时都是空闲的通讯上
我们在每一个单位的数据帧发送的过程当中
都是从空闲状态 由一个起始位开始这一次通讯
到一个停止位结束 而下一笔通讯在空闲的间隔
结束之后又是由一个起始位0和1的这个跳变
告知接收端 又一个新的帧开始了
所以我们非常容易的将我的每一笔通讯
都以这个数据帧的起始位来发起和对齐
那么换言之 在一个数据帧的长度内
接收和发送两端的时钟
没有出现一个比特以上的误差
我们的数据就不会出错 换言之
这样一种数据帧的结构
就是应对我们刚才提出的那个问题
避免异步通讯里 收和发两端的时钟
误差的累计 避免这样一种误差的累计
使它以帧为单位来进行通讯
保证每一个帧的数据结构正确就可以了
那么细节到这个帧里头 我们很关心起始位
和停止位之间 我们的数据究竟怎么发送的呢
有两个非常基本的概念
我们可能在软件或计算机里经常会学到
称为LSB和MSB
LSB是Least significant bit
MSB是Most significant bit
它的含义就是比较有含义
比较有意义的那个比特
和比较没有意义那个比特 我们称为最低位
和最高位这个非常好记 在一个多位数
比如十进制数里头987 你会发现7这个位
每错1只改变1 9这个位每错1改变100
所以我们说越是高位就越是MSB 越是低位
越是LSB 那我们UART的异步串行通讯的
这样一个数据帧里头约定好了
如果你要发送一个字节 总是把这个字节的LSB
先发跟在起始位的后面 MSB后发跟在停止位的
前头这样依次把一个字节
一个比特一个比特发送出来
所以这样一个数据帧是由起始位
再从低位高位一直到最高位 把一个字节
发送出来再到停止位结束
那么如果看我们数据帧的结构里头
我们还有可能会有一个奇偶校验位
来对这一个字节的发送是否正确
提供一个检查和校验的信息
这在我们后面的单元里头会讲
所以我们描述了这样一个UART的规定的
数据帧的结构 希望大家能够深入地加以理解
特别是理解他为什么要做这样的设计
以及我们以后的USB 以太网的通讯
为什么会有数据帧的结构
那么对于刚才讲的所有这些特性
我一个一个去讲就很费劲儿
那么我们讲异步串行通讯 往往要通过编程
大家注意我们往往在使用异步串行通信的时候
或者是它的发送和接收端都是大家自己写的程序
你就得约定好你的发送和接收端采用同样的速率
同样的数据结构来进行数据的发送和接收
他们才能通讯上 或者那是我们用一个MCU
微控制器去读写一个GPS模块 一个GSM模块
一个设备 那么这个设备
一定会约束好他的通讯协议
我必须按他所要求的速率和结构跟它通讯
那么这样一些细节 如果按刚才这样
一个一个量来讲就非常的费劲
我们往往会把它缩写成一个字符串 采用波特率
这个每个字节是几个比特 有没有奇偶校验位
停止位是一位宽还是两位宽 这些信息加以整合
比如说写成9600 8N1这样的模式
就代表 波特率是9600
换言之这一个比特就是1/9600秒
然后呢当代的计算机 我们很多时候一个字节
都是八个比特 所以每笔通讯数据发送八个比特
N代表我目前没有使用奇偶校验 不存在这一位
以及停止位采用一个比特宽 一旦这些约束好了
我们自己编程 把收发端都这样配置
就可以完成通讯 或者我们按照我们的设备
GPS GSM模块的要求 它的芯片手册的要求
来设置我们的UART串行通讯端
就可以完成跟它的通讯 那么这样 我们就深入地
理解了我们这样一个异步串行通讯数据帧的结构
那么考一考大家 我们这样一种通讯帧
如果采用了9600波特率 8N1 这样一种数据结构
我们每秒钟可以完成多少个字节的数据的传输
收发呢 是9600直接除以8吗 大家想一想
我在这里不给答案 当作我们的思考题
所以呢我们回顾一下我们 对于异步串行通讯
UART或者SCI这样一种概念的总结
大家再想一想它的概念 它是串行的
在一个引脚上数据一个比特一个比特发送
它是异步的 收发两端并没有共享时钟
那么在我们现在这个简单结构里 它是点对点的
你发我收 我收你发 当然隐含的他是对等的
对吧 然后呢 他是全双工 它有两个独立的引脚
一个负责a发给b 一个负责b发给a
这样一些特性构成了这样一个
异步串行点对点全双工对等的通讯方式
就是我们的UART 在英特尔的计算机术语里头
它称为UART通用的 异步的收发器
在摩托罗拉 包括Freescale的术语里头它称为SCI
也就是异步串行通信接口 他们俩是同一个东西
核心本质或者形而上的就是我们刚才讲的
那样一个数据帧的结构 而这样一种通讯方式
有非常悠久的历史 甚至比我们人类
所使用的个人电脑出现还要早
诞生于1960到1970年代
所以人类一直传承延续到今
有大量的异步串行通讯设备可以供我们使用
而我在前面所讲的那个例子
不仅是跟计算机通讯 我们所要使用的GPS的
定位模块 GSM的手机模块
往往跟我们的微控制器 你想把它玩起来
也会通过UART这样一种接口 那么接下来会讲
如何对它进行编程 和真正把这样一些模块
给玩起来 让你真的能够使用GPS和GSM手机短信
那么这个单元的讲解 就到这结束
-1.1 课程概览
--1.1 课程概览
-1.2 如何学好嵌入式系统
-2.1 计算机的基本概念、发展历史
-2.2 从晶体管到CPU
-2.3 概念CPU、微控制器MCU和嵌入式系统
-2.4 八卦计算机史
-2.5 不同领域、不同系列的嵌入式系统
-2.6 ARM历史与MKL25Z128 MCU
--2.6 ARM历史与MKL25Z128 MCU【习题】
-3.1 CPU的基本结构和运行机制
-3.2.1 堆栈的概念
--3.2.1 堆栈的概念【习题】
-3.2.2 堆栈的概念-头脑体操
-3.3.1 ARM的体系结构
--3.3.1 ARM的体系结构【习题】
-3.3.2 ARM的体系结构-头脑体操
-3.4.1 中断的概念和机制
-3.4.2 中断子程的概念和编程
-3.5 复位、时钟、存储器和总线
--3.5 复位、时钟、存储器和总线【习题】
-3.6 小结:MCU的总体结构和程序运行机制
--3.6 小结:MCU的总体结构和程序运行机制【习题】
-4.1 第一种外设:IO
-4.2 IO外设的编程实操-点亮LED
-4.3 IO外设的进阶知识
-4.4 嵌入式开发的基本概念与工具链
-4.5 嵌入式开发的进阶知识
-4.6 嵌入式开发中的C语言(上)
--4.6 嵌入式开发中的C语言(上)【习题】
-4.7 嵌入式开发中的C语言(下)
--4.7 嵌入式开发中的C语言(下)【习题】
-E0.1 实验零 开发板的初步认识与工具链的安装
-E0.2 实验零 体验一个例程的编译与下载
-E0.3 实验零 编写第一个程序:点亮核心板LED
-E1 实验一 点灯秘籍
-5.1 ARM微控制器外设学习概述
-5.2.1 ARM微控制器外设:通讯
-5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上)
--5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上)
--5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上)【习题】
-5.2.3 ARM微控制器外设:异步串行通讯UART的原理(下)
--5.2.3 ARM微控制器的外设:异步串行通讯UART的原理(下)
--5.2.3 ARM微控制器外设:异步串行通讯UART的原理(下)【习题】
-5.2.4 ARM微控制器外设:RS-232串口与USB虚拟串口
--5.2.4 ARM微控制器外设:RS-232串口与USB虚拟串口
-5.2.5 ARM微控制器外设:UART的寄存器编程(上)
--5.2.5 ARM微控制器外设:UART的寄存器编程(上)
-5.2.6 ARM微控制器外设:UART的寄存器编程(下)
--5.2.6 ARM微控制器外设:UART的寄存器编程(下)
--5.2.6 ARM微控制器外设:UART的寄存器编程(下)【习题】
-E2 实验二 UART编程实操
-5.3.1 ARM微控制器外设:IO的中断编程(上)
-5.3.2 ARM微控制器外设:IO的中断编程(下)
-5.4.1 ARM微控制器外设:定时器的原理
-5.4.2 ARM微控制器外设:定时器的编程
--5.4.2 ARM微控制器外设:定时器的编程【习题】
-E3 实验三 定时器中断编程实操
-5.5.1 ARM微控制器外设:PWM的原理
-5.5.2 ARM微控制器外设:PWM寄存器与编程
-5.5.3 ARM微控制器外设:PWM编程实例—电子音乐
--5.5.3 ARM微控制器外设:PWM编程实例—电子音乐
-E4 实验四 数码管显示编程实操
-5.6.1 ARM微控制器外设:SPI通讯简介
--5.6.1 ARM微控制器外设:SPI通讯简介【习题】
-5.6.2 ARM微控制器外设:SPI寄存器与编程
-5.6.3 ARM微控制器外设:SPI编程实例—OLED显示屏驱动
--5.6.3 ARM微控制器外设:SPI编程实例—OLED显示屏驱动
-5.7.1 ARM微控制器外设:I2C通讯简介
-5.7.2 ARM微控制器外设:I2C的通讯协议
-5.7.3 ARM微控制器外设:I2C寄存器与编程
--5.7.3 ARM微控制器外设:I2C寄存器与编程【习题】
-5.7.4 ARM微控制器外设:I2C编程实例—加速度传感器
--5.7.4 ARM微控制器外设:I2C编程实例—加速度传感器
-5.8.1 ARM微控制器外设:ADC简介
-5.8.2 ARM微控制器外设:ADC基础
-5.8.3 ARM微控制器外设:ADC寄存器与编程
-E5 实验五 ADC编程实操
-E6 挑战实验
--E6 挑战实验
-6.1 嵌入式系统的接口与设计
-6.2 嵌入式系统的实例