串口通信相关知识详解
通信的发展历史
- 最早通信:烽火台、狼烟,信件,电子通信(电话、电报、网络信号)
- 通信中最重要的两个方面:信息表示、解析方法+信息的传输方法
- 通信双方事先约定好信息的表示方法和解析方法,做到一致,否则信息不能有效传递
- 信号的传输方法是指经过编码后的通信信息如何在传输介质上传输的过程
总结:通信过程分为三个步骤:首先发送方按照信息编码方式对有效信息进行编码(编码成可以在通信线路上传输的信号形态)然后编码信息在传输介质上进行传输,输送给接收方,最后接收方接收到编码信息后进行解码,解码后可以得到可以理解的有效信息。
电子通信概念1:同步通信和异步通信
- 同步和异步的区别:首先很多地方都有同步和异步的概念,简单来说发送方和接收方在同一个节拍下工作,按照同一个时钟节拍工作,发送方和接收方没有统一的节拍,而是按照各自的节拍工作就叫做异步。
- 同步通信中,通信双方按照统一的节拍工作,所以配合很好,一般需要发送方给接收方发送信息同时发送时钟信号,接收方根据发送方给他的时钟信号来安排自己的节奏,同步通信用在通信双方交换频率固定,或者经常通信时。
- 异步通信又叫做异步通知。在双方通信频率不规定的时候(有时3ms发一次,有时候3天发一次)不适合使用同步通信,而适合异步通信。异步通信时,接收方不必一直在意发送方,发送方需要发送信号时会首先给接收方一个信息开始的起始信号,接收方接收到起始信号就认为后面紧跟着的就是有效信息,才会注意接收信息,直到收到发送方发送过来的结束标志。
电子通信概念2:电平信号和差分信号
- 电平信号和差分信号是用来描述通信线路传输方式的。也就是说如何在通信线路上表达1和0
- 电平信号的传输线中有一个参考电平线(一般是GND),然后信号线上的信号值是由信号线电平和参考线电平电压差决定
- 差分信号的传输线中没有参考电平,所有都是信号线,然后1和0的表达靠信号线之间的电压差
总结:电平信号的2根通信线之间的电平差容易受到干扰,传输容易失败,差分信号不容易受到干扰,因此传输质量比较稳定,线代通信一般用差分信号,电平信号几乎没有了。
电子与通信概念3:并行接口与串行接口
- 串行并行主要是考虑通信线的根数,就是发送方和接收方同时可以传递的信息量的多少。
- 譬如在电平信号下,1根参考电平线+1根信号线可以传递一位二进制;如果有3根线(2根信号线+1根参考线)就可以同时发送2位二进制
- 如果想同时发送8位二进制,就需要9根线
- 在差分信号下,2根线(彼此进行差分)可以发送以为二进制。而如果需要同时需要发送8位二进制,就需要16根线。
总结1:看起来似乎相同根数的通信线下电平信号要比差分信号快,但是实际还是差分信号更快,因为差分信号抗干扰能力强,因此发送周期短
总结2:看起来似乎并行接口比串行接口要快(串行接口发送一次只能发送一位二进制,而并行接口一次可以发送多位二进制),但实际上串行接口才是用的最广泛的。因为更省信号线。对传输线的要求低,成本低,串行时可以提高通信速率来提高整体通信能力,不一定非要并行
其实经过这么多年的发展,最终胜出的是:异步、串行、差分信号,譬如USB和网络通信
串口通信
串口通信的基本概念
串口通信的特点:异步、电平信号、串行
- 异步:串口通信的发送方和接受方之间没有统一的时钟信号
- 电平信号:串口通信出现的时间较早,速率较低,传输距离较近,所以干扰较小,因此当时使用了电平信号 传输。后期都改成差分信号传输了
- 串行通信:串口通信每次同时只能传输一个二进制位
RS232电平和TTL电平
- 电平信号使用信号线电平减去参考线电平得到电压差,这个电压差决定传输值是1还是0
- 在电平信号时多少V代表1,多少V代表0不是固定的,取决于电平标准。
譬如RS232电平:-3V~-15V表示1,+3V~+15V表示0。
譬如TTL电平:+5V表示1,0V表示0
总结:不管哪种电平都是用来在传输线上表示1和0,区别在于使用的环境和条件不同,RS232电平定义比较大,适合干扰大、距离远的情况,而TTL电平电压范围小,所以适合距离近且干扰小的情况
我们台式电脑后面的串口插座就是RS232接口的,在工业上用串口时都用这个,传输距离小于15米;而TTL电平一般用在电路板内部的芯片之间
对于编程来说,RS232传输还是TTL传输时没有差异的。所以电频标准对于硬件工程师更有意义,而软件工程师只需要略懂就可以(TTL电平和RS232电平不可以混接)
波特率
- 波特率(bandrate):指串口通信的速率,也就是每秒钟可以传输多少个二进制位。譬如说每秒钟可以传输9600个二进制位,也就是说传输一位二进制的时间为1/9600秒(约10us)。
- 串口通信的波特率不能随便设置,只能在某些特定的值中选择,一般最常见的波特率是9600,、115200(低端单片机如51一般为115200)
为什么波特率不可以随便指定?
- 第一:通信双方的波特率必须事先设定成相同的波特率这样才能通信,所以最好将波特路设置为大家熟知的几个数值,而不是随意指定的。
- 第二:常用的波特率经过长期的发展,就形成了共识,大家常用的就是9600和115200
起始位、数据位、奇偶校验位、停止位
串口通信时,收发是一个周期一个周期进行的,每周期传输n个二进制位。这一个周期就叫做一个通信单元,这一个周期就叫做一个通信单元,一个通信单元是由起始位、数据位、奇偶校验位、停止位组成的
- 起始位表示发送方要开始发送一个通信单元
- 数据位是一个单元中发送的有效信息
- 奇偶校验位是用来校验数据位的,以防止数据出错的
- 停止位:是发送方用来表示本通信单元的结束标志
起始位:是串口通信标准事先指定的,由通信线上的电平变化来指定
数据位:是本通信真正要发送的有效数据,串口通信一次发送多少有效数据是可以设定的(一般可选的有6、7、8、9,99%的情况都选择8位二进制位)
奇偶校验位:是用来给数据进行奇偶校验(把待校验的有效数据逐个位加起来,总和为奇数奇偶校验位为1,总和为偶数奇偶校验位为0)的,可以一定程度上防止位反转
停止位:是串口通信标准事先指定的,由通信线上的电平变化来指定。常见的有1位停止位,1.5位停止位,2位停止位。99%的情况为1位停止位
总结:串口通信时因为是异步通信,所以通信双方必须事先约定好通信参数,这些通信参数包括波特率、起始位、数据位、奇偶校验位、停止位(串口通信中起始位是唯一的,所以一般不用选择起始位)
串口通信的基本原理
三根通信线:RX、TX、GND
- 任何通信都要有信息传输的载体,可以是有线也可以是无线的
- 串口通信是有线通信,是通过串口线来通信的
- 串口通信最少需要两根(GND和信号线),可以实现单工通信,也可以使用三根线(TX、RX、GND)来实现全双工通信
- 一般开发板都会引出SoC上串口引脚直接输出TTL电平(x210开发板没有),插座用插针式插座,每个串口引出都有三根线(TX、RX、GNG)
- 可以用这些插座连接外部TTL电平
收发双方事先规定好通信参数(波特率、起始位、数据位、奇偶校验位、停止位)
串口通信属于基层基本性的通信规约,它自己本身不会去协商通信参数,需要通信前通信双方事先约定好通信参数(一般4个最重要)
串口通信的任何一个关键参数设置错误,都会导致通信失败,譬如波特率调错了,发送方没问题,接收方也能接收,但是接收到的全是乱码
信息以二进制的方式在信道上传输
串口通信的发送方每隔一段时间(时间固定为1/波特率秒)将有效信息放在通信线上,逐个二进制位的进行发送。
接收方通过定时(起始时间由读到起始标志位开始,间隔时间由波特率决定)读取通信线上的电平高低来区分发送给我的是0还是1,依次读取数据位、奇偶校验位、停止位。停止位就表示这一个单元(帧)结束,然后中间是不定长短的非通信时间(发送方有可能紧接着就发送第二帧,也可能半天都发不出第二帧,这就叫做异步通信)
总结:
- 第一,波特率非常重要,波特率错了,整个通信就乱了套了:数据位,奇偶校验位,停止位也很重要,否则可能认不清数据
- 第二,通过串口不管是发送数字还是文本还是命令等等,都要先对发送内容进行编码,编码成二进制才能逐位发送。
- 第三串口发送的一般都是字符,一般都是ASCII码编码后的字符,所以一般设置数据位为8,方便刚好发送一帧就是一个字节
RS232和TTL电平的区别?串行通信为什么是异步的?为什么串行而不是并行?
DB9接口介绍
- DB9接口是串口通信早起常用的一种规范接口。
- 串口通信在早期是计算机和外接通信的主要手段,那时候计算机都有标准配置的串口以实现和外部通信。那时候就定义了一套标准的串口规约,DB9接口就是标准接口
- DB9接口中有9根通信线,其中三根很重要,为GND、Tx、Rx,这三根线必不可少。剩余的6根都和流控有关,现代我们使用串口调试一般禁用流控(数据流控制),不然可能发生很多意想不到的问题,所以这6根线没用。
S5PV210的串口通信接口详解
S5PV210的数据手册中串口控制器工作原理
- S5PV210的数据手册中串口控制器在section8.1
- 串口的官方名称叫:universal asynchoronous reciver and transmitter,通用异步收发器,英文缩写是uart
- 英文缩写是uart,中文简称是串口
S5PV210串口控制器的工作原理框图
- (1)整个串口控制器包含transmitter和receiver两个部分,两部分功能彼此独立,transmitter负责210向外部发送信息,receiver负责从外部接收信息到210内部
- (2)总线角度来说,串口控制器是接在APB总线上的。对我们的影响是:将来计算串口控制器IDE原时钟时是以APB总线来计算的。
- (3)transmitter由发送缓冲区和移位器构成。我们要发送信息时,首先将信息编码成二进制流,然后将一帧数据(一般是8位),写入发送缓冲区,剩下的发送部分是硬件自动的)发送移位器会自动从发送缓冲区读取一帧数据,然后自动移位(移位的目的就是将一帧数据的各个位分别拿出来)将其发送到Tx通信线上
- (4)receiver由接收缓冲区和接收移位器构成,当有人通过串口线向我发送信息时,信息通过Rx通信线进入我的接收移位器,然后接收移位器自动移位将该二进制位保存到我的接收缓冲区,接受完一帧数据后,receiver会产生一个中断给CPU,CPU收到中断后即可知道receiver接受满了一帧数据,就会来读取这一帧数据。
总结:发送缓冲器和接收缓冲区是关键,发送移位器和接收移位器的工作都是自动的,首先初始化好串口控制器(初始化的实质就是读写寄存器),包括发送控制器和接收控制器。,然后要发送数据时,直接写入发送缓冲区,要接收信息时直接去接收缓冲区去取。可见,串口底层的工作(譬如怎么移位、譬如起始位怎么定义的,譬如TTL电平还是RS232电平)对程序员是隐藏的,程序员不用去管。软件工程师对串口操作的接口就是发送/接收缓冲区(实质就是寄存器,操作方法就是读写内存)
串口控制器中有一个波特率发生器,作用是产生串口发送和接收的时钟。波特率发生器其实就是个时钟分频器,它的工作需要源时钟然后内部将源时钟进行分频得到目标时钟,然后再用这个这个目标时钟产生波特率(硬件自动的)
自动流控(AFC:Auto flow control)
为什么需要流控?
- 流控的目的是让串口通信得长可靠,在发送方速率比接收方快的时候,流控可以保证发送和接收不会漏掉东西
为什么现在不用流控了?
- 现在计算机之间有更好更高级的通讯方式,串口已经基本被废弃了,现在串口的用途更多的是SoC用来输出调试信息的,由于调试信息不是非常重要的信息。而且由于硬件发展串口本身的速度已经相对很慢了,所以硬件都能协调发送和接收速率,因此流控已经失去意义了。
S5PV210串行通信接口详解2
本来串口的功能就是上节讲过的部分,但是后来技术的发展给串口叠加了一些高级功能,在像210这类高级SoC的串口控制器中都有这类高级功能。
FIFO模式及其作用
- 典型的串口设计,发送/接收缓冲区只有一个字节每次发送/接收只能处理一帧数据。这样在单片机中,但是在复杂的SoC中就会出现问题,会导致效率低下。因为CPU需要反复切换上下文
- 解决方案:将串口想办法扩展串口控制器的发送/接收缓冲区,譬如将发送/接收缓冲区设置为64字节,CPU一次过来直接给发送缓冲区64字节的代发数据。然后transmitter慢慢发,发完再找CPU再要64字节。但是串口本来的发送缓冲区是不能变的,固定为1KB,所以做了个变相的扩展,就是FIFO(first in first out)。FIFO是一种数据结构,先进先出,这里的一个大的缓冲区叫FIFO就是因为这个缓冲区的工作方式类似于FIFO
DMA模式及其作用
- (1)DMA(direct memory access):直接内存访问。DMA本来是DSP中的一种技术,DMA技术核心就是在交换数据时不需要CPU参与,模块可以自己完成
- (2)DMA模式要解决的问题和上面的FIFO模式是同一个问题,就是串口发送/接收要频繁的折腾CPU造成反复切换上下文导致系统效率低下。
- (3)传统的串口工作方式(无FIFO、无DMA)效率是最低的,适合低端单片机:高端单片机上CPU事务繁忙所以需要串口能够自己完成大量数据发送/接收。这时候就需要FIFO/DMA模式,FIFO是一种轻量级的解决方案,DMA模式适合大量数据迸发式发送/接收
IrDA模式及其用法
- IrDA其实就是红外,红外就是红外线通信(电视机,空调的遥控器就是红外通信的)
- 红外通信的原理是发送方固定间隔时间向接收方发送红外信号(表示1或0)或者不发送红外信号(表示0或者1),接收方每隔固定时间去判断有无红外信号来接收1或者0
- 分析可知红外通信和串口通信非常像,都是每隔固定时间发送1或者0(判断1和0的方式不同)给接收方来通信。因此就利用串口通信来实现了红外的发送和接收
- 210的某个串口支持IrDA模式,我们只需要向串口写数据,这些数据就会以红外光的方式发出去(当然也需要硬件支持),接收方就收这些红外数据即可解码得到发送信息。
S5PV210串行通信接口详解3
串行通信与中断的关系
串口通信分为发送/接收两个部分。发送方一般不需要(也可以使用)中断即可完成发送,接收方(一般来说必须,也可以轮询方式接收)使用中断来接收。
- 发送方可以选择使用中断,也可以选择不使用中断,使用中断的工作情景是:发送方先设置好中断并绑定一个中断处理程序,然后发送方丢一帧数据给transmitter ,transmitter耗费一段时间来发送这一帧数据。这段时间内发送方CPU可以去做别的事情,等transmitter发送完成后会产生一个TXD中断,该中断会导致事先绑定的中断处理程序执行,在中断处理程序中,CPU会切换回来继续给transmitter放一帧数据,然后CPU切换离开;不使用中断的工作情景是发送方事先禁止TXD,当然也不需要给相应的中断处理程序了。发送方CPU给一帧数据到transmitter,然后transmitter耗费一段时间来发送这帧数据,这段时间CPU没有切换去做别的事情,待我们发送方发送完成后,CPU再给他一帧数据,直到数据发完了为止。CPU是怎么知道transmitter发送完了?答案是:状态寄存器,状态寄存器中有一个位叫做发送缓冲区空标志位,当发送完成后,该标志位就会置1。CPU就可以通过不断的查看该状态为为1还是0来确定自己该什么时候发。
- 因为串口通信是异步的,异步的意思就是说发送方占主导权。也就是说发送方随时想发就发,但是接收方只有时刻等待才不会丢失数据。所以接收方不得不使用中断
210串口通信的时钟设计
串口通信为什么需要时钟?
因为串口通信需要一个稳定的波特率,所以transmitter和receiver都需要一个时钟信号。
这个时钟信号从哪里来?
- 源时钟信号是外部APB总线(PCLK_PSYS,66MHz)供给串口模块的(这就是为什么我们说串口是挂在在APB总线上的)然后进到串口控制器内部后给波特率发生器(实质上是一个分频器)分频后得到一个低频时钟,这个时钟就是给transmitter和receiver的。
串口通信中时钟的设置主要看寄存器设置
- 重点的寄存器有:寄存器源设置(为串口控制器选择原时钟,一般选择PCLK_PSYS,也可以是SCLK_UART),还有波特率发生器的两个寄存器。分别是UBRDIVn和UDIVSLTn,其中UBRDIVn寄存器是主要的设置波特率的寄存器,而UDIVSLTn使用来辅助计算波特率的,目的是为了校准波特率。