1. UART帧格式
UART:
Universal Asynchronous Receiver Transmitter 即通用异步收发器,是一种通用的串行、异步通信总线,该总线有两条数据线,可以实现全双工的发送和接收,在嵌入式系统中常用于主机与辅助设备之间的通信
通信的方式可以分为多种,按照数据传送方式可分为串行通信和并行通信.
按照通信的数据同步方式,可分为异步通信和同步通信。
按照数据的传输方向又可分为单工、半双工和全双工通信。
1.1 按数据传送方式
1.1.1 并行通信
并行通信通常是将数据字节的各位用多条数据线同时进行传送,通常是 8
位、16 位、32 位等数据一起传输。
并行通信的特点:控制简单、传输速度快;由于传输线较多,长距离传送时成本高且接收方的各位同时接收存在困难,抗干扰能力差。
1.1.2 串行通信
串行通信是指使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。其只需要少数几条线就可以在系统间交换信息,特别适用于计算机与计算机、计算机与外设之间的远距离通信。
串行通信的特点:传输线少,长距离传送时成本低,且可以利用电话网等现
成的设备,但数据的传送控制比并行通信复杂。
1.2 按数据同步方式
1.2.1 异步通信
异步通信是指**通信的发送与接收设备使用各自的时钟控制数据的发送和接收过程。**为使双方的收发协调,要求发送和接收设备的时钟尽可能一致。
异步通信是以字符(构成的帧)为单位进行传输,字符与字符之间的间隙(时间间隔)是任意的,但每个字符中的各位是以固定的时间传送的,即字符之间不一定有“位间隔”的整数倍的关系,但同一字符内的各位之间的距离均为“ 位间隔”的整数倍。
1.2.2 同步通信
同步通信时要建立发送方时钟对接收方时钟的直接控制,使双方达到完全同步。此时,传输数据的之间的距离均为“位间隔”的整数倍,同时传送的字符间不留间隙,即保持位同步关系,也保持字符同步关系。发送方对接收方的同步可以通过两种方法实现。
1.3 按数据传输方向
1.3.1 单工通信
单工是指数据传输仅能沿一个方向,不能实现反向传输。如下图所示:
1.3.2 半双工通信
半双工是指数据传输可以沿两个方向,但需要分时进行。如下图所示
1.3.3 全双工通信
全双工是指数据可以同时进行双向传输。如下图所示:
通信速率
衡量通信性能的一个非常重要的参数就是通信速率,通常以比特率(Bitrate)来表示。比特率是每秒钟传输二进制代码的位数,单位是:位/秒( bps)。如每秒钟传送 240 个字符,而每个字符格式包含 10 位(1 个起始位、1 个停止位、8 个数据位),这时的比特率为:10 位×240 个/秒 = 2400 bps
“波特率”概念,它表示每秒钟传输了多少个码元。而码元是通信信号调制的概念,通信中常用时间间隔相同的符号来表示一个二进制数字,这样的信号称为码元。如常见的通信传输中,用 0V 表示数字 0,5V 表示数字 1,那么一个码元可以表示两种状态 0 和 1,所以一个码元等于一个二进制比特位,此时波特率的大小与比特率一致;如果在通信传输中,有 0V、 2V、 4V 以及 6V 分别表示二进制数 00、 01、 10、 11,那么每个码元可以表示四种状态,即两个二进制比特位,所以码元数是二进制比特位数的一半,这个时候的波特率为比特率的一半。由于很多常见的通信中一个码元都是表示两种状态,所以我们常常直接以波特率来表示比特率。
UART帧格式
由上图可知,空闲位为高电平,也就是1,这个时候默认不接受数据,当我们要发送数据是,需要将信号置零,也就是起始位,然后就可以发送数据了,数据位数8位,当然也可以是5、6或者7位(先发低位,后发高位),然后就是校验位(由于串口通信相对更容易受到外部干扰导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验方法有奇校验 (odd)、偶校验(even)、0 校验(space)、1 校验(mark)以及无校验(noparity)),再就是停止位(为高电平1),可由 0.5、1、1.5 或 2 个逻辑1的数据位表示,最后又进入空闲位,至此,一个字节传输成功,如果要传递多个字节数据重复以上步骤即可。由于通信双方使用各自时钟,因此不支持一次传输多个数据。
UART控制器
一般情况下处理器中都会集成UART控制器 我们使用UART进行通信时候只需对其内部的相关寄存器进行设置即可
在硬件连接上,交叉链接:
2. Exynos4412下的UART控制器
先看电路图:
可以看到,外部信号连接到了主芯片上的XuTXD2/UART_AUDIO_TXD/GPA1_1和XuRXD2/UART_AUDIO_RXD/GPA1_0上,我们可以通过查看手册寻找具体的的引脚功能设置(串口)。
2.1 接口标准
串口通信的接口标准有很多,有 RS-232C、 RS-232、 RS-422A、 RS-485 等。常用的是 RS-232 和 RS-485。RS-232 其实是 RS-232C 的改进,原理是一样的。这里我们就以 RS-232C 接口进行讲解。
RS-232C 是 EIA(美国电子工业协会)1969 年修订 RS-232C 标准。RS-232C 定义了数据终端设备(DTE)与数据通信设备(DCE)之间的物理接口标准。
RS-232C 接口规定使用 25 针连接器,简称 DB25,连接器的尺寸及每个插
针的排列位置都有明确的定义,如下图所示:
RS-232C 还有一种 9 针的非标准连接器接口,简称 DB9。串口通信使用的大 多都是 DB9 接口。DB25 和 DB9 接头有公头和母头之分,其中带针状的接头是公头,而带孔状的接头是母头。9 针串口线的外观图如下图所示:
从上图中可以看到公头和母头的管脚定义顺序是不一样,这一点需要特别注
意。这些管脚都有什么作用呢? 9 针串口和 25 针串口常用管脚的功能说明如
下图所示:
在串口通信中,通常我们只使用 2、3、5 三个管脚,即 TXD、RXD、SGND,
RS-232C 对逻辑电平也做了规定,如下:
在 TXD 和 RXD 数据线上:
1.逻辑 1 为-3~-15V 的电压
2.逻辑 0 为 3~15V 的电压
在 RTS、CTS、DSR、DTR 和 DCD 等控制线上:
1.信号有效( ON 状态) 为 3~15V 的电压
2.信号无效( OFF 状态) 为-3~-15V 的电压
由此可见,RS-232C 是用正负电压来表示逻辑状态,与晶体管-晶体管逻辑集成电路(TTL)以高低电平表示逻辑状态的规定正好相反。所以这里需要电平转换—SP3232EEA。
2.2 通用异步接收机和发射机(UART)
Exynos 4412 SCP中的通用异步接收器和发射器(UART)提供四个独立的通道提供异步和串行输入/输出(I/O)端口(Ch0至3)。它还提供了一个与全球定位系统(GPS)(Ch4)通信的专用通道。所有端口都以基于中断或基于dma的模式运行。UART生成一个中断或一个DMA请求,以向CPU和UART传输数据。UART支持高达4 Mbps的比特率。每个UART信道包含两个先出(FIFO),用于接收和传输数据,如下所示:
UART包括:
- 可编程波特率
- 红外(IR)发射机/接收机
- 一个或两个停止位插入
- 5-位,6位,7位,或8位数据宽度和奇偶校验
每个UART包含:波特率发生器发射机接收机控制单元
波特率发生器使用SCLK_UART。发射机和接收机包含fifo(队列或缓存区)和数据移位器。要传输的数据被写入Tx FIFO,并复制到传输移位器。然后通过传输数据引脚(TxDn)移动数据。接收到的数据从接收数据引脚(RxDn)移位,并从移位器复制到Rx FIFO。
3. UART寄存器
(1)先设置GPA引脚功能为UART
即将GPA1CON 的[7:4]位设置位0x2(0001),TXD(发送)
GPA1CON 的[3:0]位设置位0x2(0001),RXD(接收)
(2)串口功能设置
( 2.1) ULCON2设置:
模式选择正常模式,无校验位,1位停止位,数据长度8位,
则:ULCON2的[6:0] = 00xx011(xx表示0或1都可以)
(2.2) UCON2设置:
设置UCON2为轮询模式
(2.3) UTRSTAT2设置
(2.4) 接收发送缓存区
(2.5) 波特率设置
the Baud rate is 115200 bps and SCLK_UART is 100 MHz, UBRDIV2 and UFRACVAL2 are:
DIV_VAL = (100000000/(115200 * 16)) – 1
= 54.3 – 1
= 53.3
UBRDIV2 = 53 (integer part of DIV_VAL)
UFRACVALn/16 = 0.3
Therefore, UFRACVAL2 = 4
(2.6) UTRSTAT2
4. UART编程
#include "exynos_4412.h"
void UART_Init(void)
{
/*1.将GPA1_0和GPA1_1分别设置成UART2的接收引脚和发送引脚,GPA1CON[7:0]*/
GPA1.CON = GPA1.CON & (~(0xff << 0)) | (0x22 << 0);
/*2.设置UART2的帧格式 ULCON2 8数据位-,1停止位,无校验,正常模式*/
UART2.ULCON2 = UART2.ULCON2 & (~(0x7f << 0)) | (0x3 << 0);
/*3,设置UART2的接收发送模式为轮询模式 UCON [3:0]*/
UART2.UCON2 = UART2.UCON2 & (~(0xf << 0)) | (0x5 << 0);
/*4.设置UART2的波特率为115200 UBRDIV2 UFRACVAL2*/
UART2.UBRDIV2 = 53;
UART2.UFRACVAL2 = 4;
return ;
}
void UART_send_byte(char dat)
{
/*等待发送缓存区为空*/
while(!(UART2.UTRSTAT2 & (1<<1)));
/*将要发送的数据写到发送寄存器*/
UART2.UTXH2 = dat;
return;
}
char UART_Rec_byte(void)
{
char Dat = 0;
/*判断接收寄存器是否接收到了数据*/
if(UART2.UTRSTAT2 & 1){
Dat = UART2.URXH2;
}else{
return 0;
}
return Dat;
}
int main()
{
char RecDat = 0;
UART_Init();
while(1){
RecDat = UART_Rec_byte();
if(RecDat == 0){
}else{
RecDat = RecDat+1;
UART_send_byte(RecDat);
}
}
return 0;
}