Written by CalmCat
Date: 2019/4/11 0:54
一条物理线路之上,通过一些规程或协议来控制这些数据的传输,以保证被传输数据的正确性。实现这些规程或协议的硬件和软件加到物理线路,这样就构成了数据链路。从数据发送点到数据接收点(点到点 point to point)所经过的传输途径。
作为数据的传输媒介,如电缆,用以建立、维护和拆除物理链路连接,简单说就是实质上可以看到的承载数据传输的物理介质。
主要功能是将网络地址与物理地址对应,并决定数据包从哪里发送到接收方,为数据包提供逻辑地址、选路等
简单介绍了物理层和网络层的功能,那么数据链路层介于两者之间,主要是将物理层的数据比特流封装成帧,控制帧在物理信道上的传输,包括纠错,调节发送速率等,另外提供两个实体之间数据链路的建立、维持和释放的管理工作。
计算机内部采用并行数据,不能直接把数据发到Modem,必须经过UART整理才能进行异步传输,其过程为:CPU先把准备写入串行设备的数据放到UART的寄存器(临时内存块)中,再通过FIFO(First Input First Output,先入先出队列)传送到串行设备,若是没有FIFO,信息将变得杂乱无章,不可能传送到Modem。
将由计算机内部传送过来的并行数据转换为输出的串行数据流。将计算机外部来的串行数据转换为字节,供计算机内部并行数据的器件使用。
在输出的串行数据流中加入奇偶校验位,并对从外部接收的数据流进行奇偶校验。
在输出数据流中加入启停标记,并从接收数据流中删除启停标记。
处理由键盘或鼠标发出的中断信号(键盘和鼠标也是串行设备)。
可以处理计算机与外部串行设备的同步管理问题。
UART是计算机中串行通信端口的关键部分。UART相连于产生兼容RS232规范信号的电路。RS232标准定义逻辑“1”信号相对于地为-3到-15伏,而逻辑 “0”相对于地为+3到+15伏。所以,当一个微控制器中的UART相连于PC时,它需要一个RS232驱动器来转换电平。
Uart这里指的是TTL电平的串口;RS232指的是RS232电平的串口。
TTL电平是5V的,而RS232是负逻辑电平,它定义+5~+12V为低电平,而-12~-5V为高电平。
Uart串口的RXD、TXD等一般直接与处理器芯片的引脚相连,而RS232串口的RXD、TXD等一般需要经过电平转换(通常由Max232等芯片进行电平转换)才能接到处理器芯片的引脚上,否则这么高的电压很可能会把芯片烧坏。
UART首先将接收到的并行数据转换成串行数据来传输。消息帧从一个低位起始位开始,后面是5~8个数据位,一个可用的奇偶位和一个或几个高位停止位。接收器发现开始位时它就知道数据准备发送,并尝试与发送器时钟频率同步。如果选择了奇偶,UART就在数据位后面加上奇偶位。奇偶位可用来帮助错误校验。
在接收过程中,UART从消息帧中去掉起始位和结束位,对进来的字节进行奇偶校验,并将数据字节从串行转换成并行。UART也产生额外的信号来指示发送和接收的状态。例如,如果产生一个奇偶错误,UART就置位奇偶标志。
数据传输可以首先从最低有效位(LSB)开始。然而,有些UART允许灵活选择先发送最低有效位或最高有效位(MSB)。微控制器中的UART传送数据的 速度范围为每秒几百位到1.5Mb。例如,嵌入在ElanSC520微控制器中的高速UART通信的速度可以高达1.152Mbps。UART波特率还受 发送和接收线对距离(线长度)的影响。
目前,市场上有只支持异步通信和同时支持异步与同步通信的两种硬件可用于UART。前者就是UART名字本身的含义,在摩托罗拉微控制器中被称为串行通信 接口(SCI);
UART作为异步串口通信协议的一种,工作原理是将传输数据的每个字符一位接一位地传输。
其中各位的意义如下:
起始位:先发出一个逻辑”0”的信号,表示传输字符的开始。
资料位:紧接着起始位之后。资料位的个数可以是4、5、6、7、8等,构成一个字符。通常采用ASCII码。从最低位开始传送,靠时钟定位。
奇偶校验位:资料位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验资料传送的正确性。
停止位:它是一个字符数据的结束标志。可以是1位、1.5位、2位的高电平。 由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供 计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。
空闲位:处于逻辑“1”状态,表示当前线路上没有资料传送。
波特率:是衡量资料传送速率的指标。表示每秒钟传送的二进制位数。例如资料传送速率为120字符/秒,而每一个字符为10位,则其传送的波特率为10×120=1200位/秒=1200波特。
发送逻辑对从发送FIFO 读取的数据执行“并→串”转换。控制逻辑输出起始位在先的串行位流,并且根据控制寄存器中已编程的配置,后面紧跟着数据位(注意:最低位 LSB(LSB:Least Significant Bit) 最低有效位(LSB))先输出)、奇偶校验位和停止位。
在检测到一个有效的起始脉冲后,接收逻辑对接收到的位流执行“串→并”转换。此外还会对溢出错误、奇偶校验错误、帧错误和线中止(line-break)错误进行检测,并将检测到的状态附加到被写入接收FIFO 的数据中。
波特率除数(baud-rate divisor)是一个22 位数,它由16 位整数和6 位小数组成。波特率发生器使用这两个值组成的数字来决定位周期。通过带有小数波特率的除法器,在足够高的系统时钟速率下,UART 可以产生所有标准的波特率,而误差很小。
发送时,数据被写入发送FIFO。如果UART 被使能,则会按照预先设置好的参数(波特率、数据位、停止位、校验位等)开始发送数据,一直到发送FIFO 中没有数据。一旦向发送FIFO 写数据(如果FIFO 未空),UART 的忙标志位BUSY 就有效,并且在发送数据期间一直保持有效。BUSY 位仅在发送FIFO 为空,且已从移位寄存器发送最后一个字符,包括停止位时才变无效。即 UART 不再使能,它也可以指示忙状态。BUSY 位的相关库函数是UARTBusy( )
在UART 接收器空闲时,如果数据输入变成“低电平”,即接收到了起始位,则接收计数器开始运行,并且数据在Baud16 的第8 个周期被采样。如果Rx 在Baud16 的第8 周期仍然为低电平,则起始位有效,否则会被认为是错误的起始位并将其忽略。
如果起始位有效,则根据数据字符被编程的长度,在 Baud16 的每第 16 个周期对连续的数据位(即一个位周期之后)进行采样。如果奇偶校验模式使能,则还会检测奇偶校验位。
最后,如果Rx 为高电平,则有效的停止位被确认,否则发生帧错误。当接收到一个完整的字符时,将数据存放在接收FIFO 中。
出现以下情况时,可使UART 产生中断:
FIFO 溢出错误
线中止错误(line-break,即Rx 信号一直为0 的状态,包括校验位和停止位在内)
奇偶校验错误
帧错误(停止位不为1)
接收超时(接收FIFO 已有数据但未满,而后续数据长时间不来)
由于所有中断事件在发送到中断控制器之前会一起进行“或运算”操作,所以任意时刻 UART 只能向中断产生一个中断请求。通过查询中断状态函数UARTIntStatus( ),软件可以在同一个中断服务函数里处理多个中断事件(多个并列的if 语句)。
FIFO 是“First-In First-Out”的缩写,意为“先进先出”,是一种常见的队列操作。 Stellaris 系列ARM 的UART 模块包含有2 个16 字节的FIFO:一个用于发送,另一个用于接收。可以将两个FIFO 分别配置为以不同深度触发中断。可供选择的配置包括:1/8、 1/4、1/2、3/4 和7/8 深度。例如,如果接收FIFO 选择1/4,则在UART 接收到4 个数据时产生接收中断。
发送FIFO的基本工作过程: 只要有数据填充到发送FIFO 里,就会立即启动发送过程。由于发送本身是个相对缓慢的过程,因此在发送的同时其它需要发送的数据还可以继续填充到发送 FIFO 里。当发送 FIFO 被填满时就不能再继续填充了,否则会造成数据丢失,此时只能等待。这个等待并不会很久,以9600 的波特率为例,等待出现一个空位的时间在1ms 上下。发送 FIFO 会按照填入数据的先后顺序把数据一个个发送出去,直到发送 FIFO 全空时为止。已发送完毕的数据会被自动清除,在发送FIFO 里同时会多出一个空位。
接收FIFO的基本工作过程: 当硬件逻辑接收到数据时,就会往接收FIFO 里填充接收到的数据。程序应当及时取走这些数据,数据被取走也是在接收FIFO 里被自动删除的过程,因此在接收 FIFO 里同时会多出一个空位。如果在接收 FIFO 里的数据未被及时取走而造成接收FIFO 已满,则以后再接收到数据时因无空位可以填充而造成数据丢失。
收发FIFO 主要是为了解决UART 收发中断过于频繁而导致CPU 效率不高的问题而引入的。在进行 UART 通信时,中断方式比轮询方式要简便且效率高。但是,如果没有收发 FIFO,则每收发一个数据都要中断处理一次,效率仍然不够高。如果有了收发FIFO,则可以在连续收发若干个数据(可多至14 个)后才产生一次中断然后一并处理,这就大大提高了收发效率。
完全不必要担心FIFO 机制可能带来的数据丢失或得不到及时处理的问题,因为它已经帮你想到了收发过程中存在的任何问题,只要在初始化配置UART 后,就可以放心收发了, FIFO和中断例程会自动搞定一切。
UART 可以进入一个内部回环(Loopback)模式,用于诊断或调试。在回环模式下,从Tx 上发送的数据将被Rx 输入端接收。
在某些 Stellaris 系列 ARM 芯片里,UART 还包含一个 IrDA 串行红外(SIR)编码器/ 解码器模块。IrDA SIR 模块的作用是在异步UART数据流和半双工串行SIR 接口之间进行转换。片上不会执行任何模拟处理操作。SIR 模块的任务就是要给UART 提供一个数字编码输出和一个解码输入。UART 信号管脚可以和一个红外收发器连接以实现IrDA SIR物理层连接。
1.UART线性控制寄存器ULCONn(ULCON0, R/W, Address = 0xEC00_0000)
ULCONn |
位 |
描述 |
初始状态 |
Reserved |
[7] |
|
0 |
Infra-Red Mode |
[6] |
是否使用红外模式 0=正常模式 1=红外模式 |
0 |
Parity Mode |
[5:3] |
校验方式 0XX=无奇偶校验 100=奇校验 101=偶校验 110=校验位强制为1 111=校验位强制为0 |
000 |
Number of Stop Bit |
[2] |
停止位数量 0=1个停止位 1=2个停止位 |
0 |
Word Length |
[1:0] |
数据位个数 00=5bit 01=6bit 10=7bit 11=8bit |
00 |
2.UART控制寄存器UCONn(UCON0,R/W Address = 0xEC00_0004)
UCONn |
位 |
描 述 |
初 始 值 |
Clock Selection |
[11:10] |
x0:PCLK 做比特率发生 01:UART_CLK 11 = SCLK_UART |
0 |
Tx Interrupt Type |
[9] |
0:Tx 中断脉冲触发 1:Tx 中断电平触发 |
0 |
Rx Interrupt Type |
[8] |
0:Rx 中断脉冲触发 1: Rx 中断电平触发 |
0 |
Rx Time Out Enable |
[7] |
0:接收超时中断不允许 1: 接收超时中断允许 |
0 |
Rx Error Status Interrupt Enable |
[6] |
0:不产生接收错误中断 1: 产生接收错误中断 |
0 |
Loopback Mode |
[5] |
0:正常模式 1: 发送直接传给接收方式(Loopback) |
0 |
Reserved |
[4] |
0:正常模式发送 1: 发送间断信号 |
0 |
Transmit Mode |
[3:2] |
发送模式选择 00:不允许发送 01:中断或查询模式 10:DMA0请求 11:DMA1 请求 |
00 |
Receive Mode |
[1:0] |
接收模式选择 00:不允许接收 01:中断或查询模式 10:DMA0请求 11:DMA1请求 |
00 |
3.UART FIFO 控制寄存器UFCONn(UFCON0,R/W,ADDRESS = 0xEC00_0008)
UFCONn |
位 |
描 述 |
初 始 值 |
Tx FIFO Trigger Level |
[7:6] |
决定发送FIFO的触发位置 00=0个字节时触发 01=16个字节时触发 10=32个字节时触发 11=48个字节时触发 |
00 |
Rx FIFO Trigger Level |
[5:4] |
决定接收FIFO的触发位置 00=1个字节时触发 01=8个字节时触发 10=16个字节时触发 11=32个字节时触发 |
00 |
Reserved |
[3] |
保留 |
0 |
Tx FIFO Reset |
[2] |
Tx FIFO复位后是否清零 0=不清零 1=清零 |
0 |
Rx FIFO Reset |
[1] |
Rx FIFO复位后是否清零 0=不清零 1=清零 |
0 |
FIFO Enable |
[0] |
使能FIFO功能 0=不使能 1=使能 |
0 |
4.UART MODEM控制寄存器UMCONn(UMCON0,R/W,ADDRESS = 0xEC00_000C)
UMCONn |
位 |
描 述 |
初 始 值 |
RTS trigger Level |
[7:5] |
如果自动流控制位使能, 则以下位将决定失效nRTS信号: 000 = RX FIFO 填充63字节 001 = RX FIFO 填充56字节 010 = RX FIFO 填充48字节 011 = RX FIFO 填充40字节 100 = RX FIFO 填充32字节 101 = RX FIFO 填充24字节 110 = RX FIFO 填充16字节 111 = RX FIFO 填充8 字节 |
000 |
Auto Flow Control (AFC) |
[4] |
0:不允许使用AFC模式 1:允许使用AFC 模式 |
0 |
Reserved |
[3:1] |
保留,必须全为0 |
00 |
Request to Send |
[0] |
0:不激活nRTS 1:激活nRTS |
0 |
5.发送寄存器UTXHn和接收寄存器URXHn
这两个寄存器存放着发送和接收的数据,在关闭FIFO的情况下只有一个字节8位数据。需要注意的是,在发生溢出错误时,接收的数据必须被读出来,否则会引发下次溢出错误。
6.比特率分频寄存器UBRDIVn
用于串口比特率的设置。S5PC100引入了UDIVSLOTn,使得波特率的设置比早期处理器更加精确。下面以设置波特率为115200为目标,介绍设置方法。
DIV_VAL = (PCLK / (bps*16 ) ) -1
=66.75M/115200*16 - 1 //PCLK由系统时钟提供,此为设定66.75M
=35.214
UBRDIVn = 35(DIV_VAL的整数部分)。
(UDIVSLOTn中1的数量)/16 = 0.2。
(UDIVSLOTn中1的数量) = 3。
根据手册中的建议3 0x0888(0000_1000_1000_1000b)11 0xDDD5(1101_1101_1101_0101b)选择"UDIVSLOTn = 0x0888; "。
7.串口状态寄存器UTRSTATn(UTRSTAT0,R,ADDRESS = 0xEC00_0010)
UTRSTATn |
位 |
描 述 |
初 始 值 |
Transmitter empty |
[2] |
发送缓冲和发送移位寄存器是否都为空 0=否11 1=是 |
1 |
Transmit buffer empty |
[1] |
关闭FIFO的情况下,发送缓冲是否为空 0=不为空 1=空 |
1 |
Receive buffer data ready |
[0] |
关闭FIFO的情况下,接收缓冲是否为空 0=空 1=不为空 |
0 |
数据发送的思想是,当启动字节发送时,通过TxD先发起始位,然后发数据位和奇偶数效验位,最后再发停止位,发送过程由发送状态机控制,每次中断只发送1个位,经过若干个定时中断完成1个字节帧的发送。
数据接收的思想是,当不在字节帧接收过程时,每次定时中断以3倍的波特率监视RxD的状态,当其连续3次采样电平依 次为1、0、0时,就认为检测到了起始位,则开始启动一次字节帧接收,字节帧接收过程由接收状态机控制,每次中断只接收1个位,经过若干个定时中断完成1 个字节帧的接收。
为了提高串口的性能,在发送和接收上都实现了FIFO功能,提高通信的实时性。FIFO的长度可以进行自由定义,适应用户的不同需要。
波特率的计算按照计算公式进行,在设置最高波特率时一定要考虑模拟串口程序代码的执行时间,该定时时间必须大于模拟串口的程序的规定时间。单片机的执行速度越快,则可以实现更高的串口通讯速度
一般uart控制器在嵌入式系统里面都做在cpu一起,像飞思卡尔的IMX6芯片就是这样,有多个uart控制器。
引脚介绍(COM口比较多pin,但是常用的也是这几个):
VCC:供电pin,一般是3.3v,在我们的板子上没有过电保护,这个pin一般不接更安全
GND:接地pin,有的时候rx接受数据有问题,就要接上这个pin,一般也可不接
RX:接收数据pin
TX:发送数据pin
在调试的时候, 多数情况下我们只引出rx,tx即可。 比如调试gps模块, IC数据直接通过uart上报,我就直接用了两个线连出了rx,tx,连上串口转USB小板, 电脑从串口直接获取数据,这样跳过了开发板,测试了gps的数据有没有问题。
UART有4个pin(VCC, GND, RX, TX), 用的TTL电平, 低电平为0(0V),高电平为1(3.3V或以上)。
(Direct Memory Access,直接内存存取) 是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依赖于 CPU 的大量中断负载。否则,CPU 需要从来源把每一片段的资料复制到暂存器,然后把它们再次写回到新的地方。在这个时间中,CPU 对于其他的工作来说就无法使用。
这里讲到的“流”,当然指的是数据流。数据在两个串口之间传输时,常常会出现丢失数据的现象,或者两台计算机的处理速度不同,如台式机与单片机之间的通讯,接收端数据缓冲区已满,则此时继续发送来的数据就会丢失。现在我们在网络上通过MODEM进行数据传输,这个问题就尤为突出。流控制能解决这个问题,当接收端数据处理不过来时,就发出“不再接收”的信号,发送端就停止发送,直到收到“可以继续发送”的信号再发送数据。因此流控制可以控制数据传输的进程,防止数据的丢失。 PC机中常用的两种流控制是硬件流控制(包括RTS/CTS、DTR/CTS等)和软件流控制XON/XOFF(继续/停止),下面分别说明。
硬件流控制常用的有RTS/CTS流控制和DTR/DSR(数据终端就绪/数据设置就绪)流控制。硬件流控制必须将相应的电缆线连上,用RTS/CTS(请求发送/清除发送)流控制时,应将通讯两端的RTS、CTS线对应相连,数据终端设备(如计算机)使用RTS来起始调制解调器或其它数据通讯设备的数据流,而数据通讯设备(如调制解调器)则用CTS来起动和暂停来自计算机的数据流。这种硬件握手方式的过程为:我们在编程时根据接收端缓冲区大小设置一个高位标志(可为缓冲区大小的75%)和一个低位标志(可为缓冲区大小的25%),当缓冲区内数据量达到高位时,我们在接收端将CTS线置低电平(送逻辑0),当发送端的程序检测到CTS为低后,就停止发送数据,直到接收端缓冲区的数据量低于低位而将CTS置高电平。RTS则用来标明接收设备有没有准备好接收数据。
常用的流控制还有还有DTR/DSR(数据终端就绪/数据设置就绪)。我们在此不再详述。
由于电缆线的限制,我们在普通的控制通讯中一般不用硬件流控制,而用软件流控制。一般通过XON/XOFF来实现软件流控制。常用方法是:当接收端的输入缓冲区内数据量超过设定的高位时,就向数据发送端发出XOFF字符(十进制的19或Control-S,设备编程说明书应该有详细阐述),发送端收到XOFF字符后就立即停止发送数据;当接收端的输入缓冲区内数据量低于设定的低位时,就向数据发送端发出XON字符(十进制的17或Control-Q),发送端收到XON字符后就立即开始发送数据。一般可以从设备配套源程序中找到发送的是什么字符。
当软件里用了流控制时,应做详细的说明,如何接线,如何应用。应该注意,若传输的是二进制数据,标志字符也有可能在数据流中出现而引起误操作,这是软件流控制的缺陷,而硬件流控制不会有这个问题。
看来许多人还没有真正理解FIFO的作用和优点,仍然停留在每收发一个字符就要中断处理一次的老思路上。UART收发FIFO主要是为了解决收发中断过于频繁而导致的CPU效率不高的问题。
FIFO的必要性。在进行UART通信时,中断方式比轮询方式要简便且效率高。但是,如果没有收发FIFO,则每传输一个数据(5~8位)都要中断处理一次,效率仍然不高。如果有了收发FIFO,则可以在连续收发若干个数据(可多至14个)后才产生一次中断,然后一起处理。这就大大提高了收发效率。
接收超时问题。如果没有接收超时功能,则在对方已经发送完毕而接收FIFO未填满时并不会触发中断(FIFO满才会触发中断),结果造成最后接收的有效数据得不到处理的问题。有了接收超时功能后,如果接收FIFO未填满而对方发送已经停,则在不超过3个数据的接收时间内就会触发超时中断,因此数据会照常得到处理。
发送时,只要发送FIFO不满,数据只管往里连续放,放完后就直接退出发送子程序。随后,FIFO真正发送完成后会自动产生中断,通知主程序说:我已经完成真正的发送。 接收时,如果对方是连续不间断发送,则填满FIFO后会以中断的方式通知主程序说:现在有一批数据来了,请处理。
如果对方是间断性发送,也不要紧,当间隔时间过长时(2~3个字符传输时间),也会产生中断,这次是超时中断,通知主程序说:对方可能已经发送完毕,但FIFO未满,也请处理。