UART异步串行口UART异步串行口简介数据通信的基本方式可分为并行通信与串行通信两种:并行通信:是指利用多条数据传输线将一个资料的各位同时传送。
它的特点是传输速度快,适用于短距离通信,但要求通讯速率较高的应用场合。
串行通信:是指利用一条传输线将资料一位位地顺序传送。
特点是通信线路简单,利用简单的线缆就可实现通信,降低成本,适用于远距离通信,但传输速度慢的应用场合。
UART 异步串行口的传输格式异步通信以一个字符为传输单位,通信中两个字符间的时间间隔是不固定的,然而在同一个字符中的两个相邻位代码间的时间间隔是固定的。
通信协议(通信规程):是指通信双方约定的一些规则。
在使用异步串口传送一个字符的信息时,对资料格式有如下约定:规定有空闲位、起始位、资料位、奇偶校验位、停止位。
通讯时序图如下:开始前,线路处于空闲状态,送出连续“1”。
传送开始时首先发一个“0”作为起始位,然后出现在通信线上的是字符的二进制编码数据。
每个字符的数据位长可以约定为5 位、6 位、7 位或8 位,一般采用ASCII 编码。
后面是奇偶校验位,根据约定,用奇偶校验位将所传字符中为“1”的位数凑成奇数个或偶数个。
也可以约定不要奇偶校验,这样就取消奇偶校验位。
最后是表示停止位的“1”信号,这个停止位可以约定持续1 位、1.5 位或2 位的时间宽度。
至此一个字符传送完毕,线路又进入空闲,持续为“1”。
经过一段随机的时间后,下一个字符开始传送才又发出起始位。
每一个数据位的宽度等于传送波特率的倒数。
微机异步串行通信中,常用的波特率为110,150,300,600,1200,2400,4800,9600 ,19200,38400,115200等。
S3C2410的异步串行口1S3C2410 的UART(通用异步串行口)单元提供三个独立的异步串行I/O 端口,每个都可以在中断和DMA 两种模式下进行。
UART支持的最高波特率达230.4kbps。
每个UART通道包含2 个16 位FIFO 分别提供给接收和发送。
每个UART 包含波特率发生器,接收器,发送器和控制单元。
波特率发生器以PCLK或UCLK为时钟源。
发送器和接收器包含16 字节FIFO 寄存器和移位寄存器,当发送数据的时候,数据先写到FIFO 然后拷贝到发送移位寄存器,然后从数据输出端口(TxDn)依次被移位输出。
被接收的数据也同样从接收端口(RxDn)移位输入到移位寄存器,然后拷贝到FIFO 中。
异步串行口的操作数据发送操作数据发送帧的格式是可编程的,它包含一个开始位,5 到8 个数据位,一个可选的奇偶位和一个或两个停止位,这些可以通过线性控制器(ULCONn)来设置。
发送器也能够产生发送中止条件。
中止条件迫使串口输出保持在逻辑0 状态,这种状态保持一个传输帧的时间长度。
通常在一帧传输数据完整地传输完之后,在通过这个全0 状态将中止信号发送给对方。
中止信号发送之后,传送数据连续放到FIFO 中(在不使用FIFO 模式下,将被放到输出保持寄存器)。
数据接收操作与数据发送一样,数据接收的帧也是可以编程的,它包含一个开始位,5 到8 个数据,一个可选的奇偶位和一位或两位停止位,它们都是通过线性控制器(ULCONn)来设置的。
接收器能够检测溢出错误,奇偶校验错误,帧错误和中止状况,每种情况下都将会将一个错误标志置位。
UART 异步串行口的波特率发生器每个UART 的波特率发生器为传输提供了串行移位时钟。
波特率产生器的时钟源可以从S3C2410 的内部系统时钟或UCLK 中来选择。
波特率由时钟源(PCLK 或UCLK)16 分频然后被UART 波特率除数寄存器(UBRDIVn)指定的16 位除数决定。
因此,UBRDIVn 的值可以按照下式确定:UBRDIVn=(int)(PCLK/(bps*16))-1 ,其中bps为波特率。
例如,如果波特率为115200bps 且PCLK 或UCLK 为40MHz,则UBRDIVn 为:UBRDIVn =(int)(40000000)(115200*16))-1= (int)(21.7)-1= 21-1 = 20UART异步串行口波特率发生器的误差极限UART传输10bit数据的时间误差应该小于1.87%(3/160)。
tUPCLK = (UBRDIVn + 1) x 16 x 10 / PCLK 实际的传输10bit所需时间。
tUEXACT = 10 / baud-rate 理想情况下传输10位需要的时间。
UART error=(tUPCLK – tUEXACT) / tUEXACT x 100%异步串行口的相关寄存器线路控制寄存器(ULCON)2线性控制寄存器,主要用来规定传输帧的格式。
下面表格是线控制寄存器的地址34发送/接收状态寄存器(UTRSTA T)5错误状态寄存器(UERSTA T)FIFO状态寄存器(UFSTA T)6MODEM状态寄存器(UMSTA T)发送缓冲寄存器(UTXHn)7接收缓冲寄存器(URXHn)波特率除数寄存器实验内容根据前面的原理介绍,写一个程序来测试串口的基本功能。
异步串口实验步骤从上面的寄存器介绍可以看到,与UART有关的寄存器共有11*3(因为有3个UART通道)之多。
本实验使用UART0。
1.初始化8把使用到的的引脚GPH2、GPH3定义为TXD0、RXD0:GPHCON |= 0xa0GPHUP |= 0x0c (上拉)ULCON0 ( UART channel 0 line control register ):设为0x03此值含义为:8个数据位,1个停止位,无校验,正常操作模式(与之相对的是Infra-Red Mode,此模式表示0、1的方式比较特殊)。
UCON0 (UART channel 0 control register ):设为0x245除了位[3:0],其他位都使用默认值。
位[3:0]=0b0101表示:发送、接收都使用―中断或查询方式‖——本实验使用查询方式。
UFCON0 (UART channel 0 FIFO control register ):设为0x00每个UART内部都有一个16字节的发送FIFO和接收FIFO,但是本实验不使用FIFO,设为默认值0UMCON0 (UART channel 0 Modem control register ):设为0x00本实验不使用流控,设为默认值0UBRDIV0 ( R/W Baud rate divisior register 0 ):设为12本实验未使用PLL,PCLK=12MHz,设置波特率为115200,则由公式UBRDIVn = (int)(PCLK / (bps x 16) ) –1可以计算得UBRDIV0,请使用S3C2410数据手册第314页的误差公式验算一下此波特率是否在可容忍的误差范围之内,如果不在,则需要更换另一个波特率(本实验使用的115200是符合的)。
2.发送数据UTRSTA T0 ( UART channel 0 Tx/Rx status register ):位[2]:无数据发送时,自动设为1。
当我们要使用串口发送数据时,先读此位以判断是否有数据正在占用发送口。
位[1]:发送FIFO是否为空,本实验未用此位位[0]:接收缓冲区是否有数据,若有,此位设为1。
本实验中,需要不断查询此位一判断是否有数据已经被接收。
UTXH0 (UART channel 0 transmit buffer register ):把要发送的数据写入此寄存器。
3.接收数据UTRSTA T0:如同上述―2、发送数据‖所列,我们用到位[0]URXH0 (UART channel 0 receive buffer register ):异步串口实验代码主函数void Main(void){int i,j;sysinit(); //系统初始化代码,在这里不关心它Uart_Init(0,115200); //初始化串口,115200是波特率定义见下面说明Uart_Select(0); //选择串口0,标准库函数,可直接调用Uart_Printf("\nWelcom to Uart Test!\n"); //在屏幕打印,标准库函数,可直接调用。
Uart_Printf("Baud rate=115200, no flow control\n");9i = 0;while(1){Uart_Printf("i=%d \n", i++); //从串口格式化输出for (j=0; j<0xffffff; j++); //延时}}主函数中调用的函数的定义void Uart_Init(int pclk, int baud){int i;if(pclk == 0)pclk = PCLK; //参数pclk为0表示选用的时钟为PCLK。
rUFCON0 = 0x0; //UART 通道0 FIFO control register, FIFO禁止,不使用。
rUFCON1 = 0x0; //UART 通道1 FIFO control register, FIFO禁止,不使用。
rUFCON2 = 0x0; //UART 通道2 FIFO control register, FIFO禁止,不使用。
rUMCON0 = 0x0; //UART 通道0 MODEM control register, AFC禁止,不使用。
rUMCON1 = 0x0; //UART 通道1 MODEM control register, AFC禁止,不使用。
//UART0rULCON0 = 0x3; //Line control register,对照寄存器的定义,可以知道这样赋值定义了数据传输格式:工作在正常模式,没有校验位,1个停止位每帧,每帧8位数据。
rUCON0 = 0x245; // 发送和接收都采用查询或中断模式。
rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 ); //波特率divisior register 0,根据公式计算,注意要验证误差范围,误差计算公式文档中已经给出。
//UART1,与UART0相似rULCON1 = 0x3;rUCON1 = 0x245;rUBRDIV1=( (int)(pclk/16./baud) -1 );//UART2,与UART0相似rULCON2 = 0x3;rUCON2 = 0x245;rUBRDIV2=( (int)(pclk/16./baud) -1 );for(i=0;i<100;i++); //延时一小会儿}该实验成功后的结果可参看文件夹中的图片。