++++++++++++++++++++++++++++++++++++++++++
本文转载自mr_raptor的专栏,感谢mr_raptor大神。
http://blog.csdn.net/mr_raptor/article/details/6556133
++++++++++++++++++++++++++++++++++++++++++
通用异步接收器和发送器(Universal Asynchronous Receiver and Transmitter)简称UART。通常是嵌入式设备中默认都会配置的通信接口。这是因为,很多嵌入式设备没有显示屏,无法获得嵌入式设备实时数据信息,通过UART串口和超级终端相连,打印嵌入式设备输出信息。并且在对嵌入式系统进行跟踪和调试时,UART串口是必要的通信手段。比如:网络路由器,交换机等都要通过串口来进行配置。UART串口还是许多硬件数据输出的主要接口,如GPS接收器就是通过UART串口输出GPS接收数据的。
S3C2440 UART控制器,提供了三个独立的异步串行I/O端口,每个端口都可以在中断模式或DMA模式下工作,换而言之,UART可以生成中断或DMA请求用于CPU和UART之间的数据传输。UART串口挂接在APB总线上,APB总线最高可以达到50MHz工作频率,在使用APB时钟频率时可以达到最高115.2Kbps波特率的通信速度。如果UART串口接收外部设备提供UEXTCLK(外部时钟),UART可以在更高的速度下工作。每个UART串口在接收装置和发送装置里分别包含一个64Byte的FIFO缓冲区,用于缓存发送数据和接收数据。
由于UART是串行异步通信方式,因此在UART通信过程中每次只能传输1bit,若干位组成一个数据帧(frame),帧是UART通信中最基本单元,它主要包含:开始位,数据位,校验位(如果开启了数据校验,要包含校验位),和停止位,帧结构如图1所示。
图1 UART数据帧结构
UART在通信之前要在发送端和接收端约定好帧结构,也就是约定好传输数据帧格式。
开始位:必须包含在数据帧中,表示一个帧的开始。
数据位:可选5/6/7/8位,该位长度可由编程人员指定。
校验位:如果在开启了数据校验时,该位必须指定。
停止位:可选1,2位,该位长度可由编程人员指定。
通信双方约定好帧格式后,指定同一波特率,以保证双方数据传输的同步。
S3C2440 UART串口工作原理
每个UART包含一个波特率产生器,发送器,接收器和一个控制单元,如图2所示
图2 UART硬件结构
UART是以异步方式实现通信的,其采样速度由波特率决定,波特率产生器的工作频率可以由PCLK(外围设备频率),FCLK/n(CPU工作频率的分频),UEXTCLK(外部输入时钟)三个时钟作为输入频率,波特率设置寄存器是可编程的,用户可以设置其波特率决定发送和接收的频率。发送器和接收器包含了64Byte的FIFO和数据移位器。UART通信是面向字节流的,待发送数据写到FIFO之后,被拷贝到数据移位器(1字节大小)里,数据通过发送数据管脚TXDn发出。同样道理,接收数据通过RXDn管脚来接收数据(1字节大小)到接收移位器,然后将其拷贝到FIFO接收缓冲区里。
(1)数据发送
发送的数据帧是可编程的,它的一个帧长度是用户指定的,它包括一个开始位,5~8个数据位,一个可选的奇偶校验位和1~2个停止位,数据帧格式可以通过设置ULCONn寄存器来设置(如图3)。发送器也可以产生一个终止信号,它由一个全部为0的数据帧组成。在当前发送数据被完全传输完以后,该模块发送一个终止信号。在终止信号发送后,它可以继续通过FIFO或发送保持寄存器(NON-FIFO)发送数据。
(2)数据接收
同样接收端数据也是可编程的,接收器可以侦测到溢出错误奇偶校验错误,帧错误和终止条件,每个错误都可以设置一个错误标志。
溢出错误是指在旧数据被读取到之前,新数据覆盖了旧数据
奇偶校验错误是指接收器侦测到了接收数据校验结果失败,接收数据无效
帧错误是指接收到的数据没有一个有效的停止位,无法判定数据帧结束
终止条件是指RxDn接收到保持逻辑0状态持续长于一个数据帧的传输时间
(3)自动流控AFC(Auto Float Control)
UART0和UART1支持有nRTS和nCTS的自动流控,UART2不支持流控。在AFC情况下,通信双方nRTS和nCTS管脚分别连接对方的nCTS和nRTS管脚。通过软件控制数据帧的发送和接收。
在开启AFC时,发送端接收发送前要判断nCTS信号状态,当接收到nCTS激活信号时,发送数据帧。该nCTS管脚连接对方nRTS管脚。接收端在准备接收数据帧前,其接收器FIFO有大于32个字节的空闲空间,nRTS管脚会发送激活信号,当其接收FIFO小于32个字节的空闲空间,nRTS必须置非激活状态。如图3所示。
图3 自动流控数据传输
(4)波特率
在UART中波特率发生器为发送器和接收器提供工作时钟。波特率发生器的时钟源可以选择S3C2440A的内部系统时钟(PCLK,FCLK/n)或UEXTCLK(外部时钟源),可以通过设置UCONn寄存器来设置波特率发生器的输入时钟源。通常我们选择使用PCLK作为UART工作时钟。
UART控制器中没有对波特率进行设置的寄存器,而是通过设置一个除数因子,来决定其波特率。其计算公式如下:
UART除数(UBRDIVn) = (int) ( UART时钟 / (buadrate * 16 ) ) - 1
其中:
UBRDIVn的取值范围应该为1~2^16-1。
UART时钟,可以选择 PCLK,FCLK/n或者UEXTCLK
例如:
波特率为115200bps,PCLK时钟为其工作频率,采用50MHz,则UBRDIVn为:
UBRDIVn = (int) (50M / (115200 x 16) ) - 1 = 26
在系统时钟未初始化时,PCLK = 12MHz,如果波特率采用57600bps,那么UBRDIVn为:
UBRDIVn = (int) (12M / (57600 x 16)) - 1 = 12
当然,UBRDIVn应该是从1~(2^16-1),只有在使用小于PCLK的UEXTCLK时设置为0(旁路模式)。
(5)波特率的错误容忍率(Baud-Rate Error Torlerance)
数据信号在传输过程中由于外界电磁干扰,信号减弱等原因,当时钟频率较低,传输速率较高时会产生误差,当误差达到一定值时,会出现数据信号不能正常识别,造成通信异常。好比如,在普通列车轨道上试图行驶高速列车一样,由于高速列车对轨道要求很高,当速度达到一定程度,很可能造成事故。业界的波特率的错误容忍率为1.87%(3 / 160),如果大于该值则应该选择较低的波特率或提高输入时钟频率。
错误容忍率计算公式为:
UART Error = (tUPCLK - tUEXACT) / tUEXACT * 100%
注:
tUPCLK为UART的真实工作时钟频率:tUPCLK = (UBRDIVn + 1) * 16 * 1Frame / PCLK
tUEXACT为UART理想工作时钟频率:tUEXACT = 1Frame / baudrate
其中:1Frame 为数据帧的长度 = 开始位 + 数据位 + 可选校验位 + 停止位
假如,波特率采用115200bps,PCLK时钟为50MHz,波特率除数因子UBRDIVn为26(通过前面UBRDIVn计算公式算出),采用1个停止位,8个数据位,无校验的8N1方式通信时,其错误容忍率为:
tUPCLK = 27 * 16 * 10 / 50M = 0.0000864
tUEXACT = 10 / 115200 = 0.0000868
UART Error = | 0.0000864 - 0.0000868 | / 0.0000868 = 0.46%
在开发板没有初始化系统时钟前,开发板工作在12MHz下,假如我们将波特率设置为115200bps,采用PCLK为系统默认时钟12MHz,8N1数据帧格式通信,那么:
UBRDIVn = (int)(12M / (115200 * 16)) - 1 = 6
其错误容忍率:
tUPCLK = 7 * 16 * 10 / 12M = 0.0000933
tUEXACT = 10 / 115200 = 0.0000868
UART Error = | 0.0000933 - 0.0000868 | / 0.0000868 = 7.5%
其错误容忍率大于1.86%,因此在12MHz频率下,波特率不能设置为115200,现在将波特率设置为56700bps,采用8N1数据帧格式通信,那么:
UBRDIVn = (int)(12M / (57600 * 16)) - 1 = 12
tUPCLK = 13 * 16 * 10 / 12M = 0.000173
tUEXACT = 10 / 57600 = 0.0001736
UART Error = | 0. 000173 - 0. 0001736 | / 0. 0001736 = 0.345%
采用波特率为56700bps,8N1数据帧格式通信时,其错误容忍率小于标准的1.86%,因此可以正常工作。
MINI2440 UART串口
图4 MINI2440开发板串口硬件图
图4为MINI2440开发板引出UART串口接线图,它采用DB9接口公头,其有9根信号线,UART通信过程中用到了信号线2 RSTXD0(数据发送管脚)它和串口线母头TXDx信号线相接(x代表0号,1号,2号串口),信号3 RSRXD0(数据接收管脚)和串口线母头RXDx相接(x代表0号,1号,2号串口),信号线5(接地管脚),信号线7 RSCTS0(数据发送流控制管脚)和串口线母头nCTSx相接,信号线8 RSRTS0(数据接收流控制管脚)和串口线母头nRTSx相接。如果UART中没有开启AFC流控的话,只要用到信号线2,信号线3和信号线5。
图5 MIMI2440串口管脚接线
由图5可以看出,TXD0和RXD0连接到CPU的GPH2和GPH3管脚上的,而GPH2和GPH3是CPU复用管脚,因此我们要对GPH2和GPH3对应寄存器进行设置,其对应寄存器为GPHCON,如图6所示。
图6 GPHCON寄存器
CPHCON[5:4]和GPHCON[7:6]为TXD和RXD管脚设置位,将其功能设置为UART专用通信管脚,因此设置为0b10,分别用于UART数据的发送和接收,即GPHCON |= 0xa0
图7 GPHUP上拉电阻设置寄存器
GPHUP上拉电阻设置寄存器:上拉电阻用来稳定电平信号,保障传输数据的正确,GPHUP里设置其内部上拉,即GPHUP=0x0
图8 ULCONn寄存器
通过设置ULCON0来设置UART0通信方式,ULCON0[6]选择通信方式为普通模式操作或红外Tx/Rx模式,ULCON[5:3]设置串口0校验方式,ULCON0[2]设置串口0停止位数,ULCON0[1:0]设置串口0的数据位数。
我们选择普通通信模式,无校验位,1个停止位,8个数据位的数据通信方式,因此:ULCON0=0x03;
图9 UART0串口控制器寄存器(UCON0)
通常UART串口采用PCLK作为输入工作时钟,采用简单的轮询方式进行数据接收和发送,不开启数据接收超时,数据产生错误时不产生错误状态中断,因此,UCON0=0x05
图10 UART FIFO控制寄存器(UFCON0)
图11 UART MODEM控制寄存器(UMCON0)
图11 UART 发送/接收状态寄存器
图12 UART 发送缓存寄存器(UTXH0)
图13 UART接收缓存寄存器(URXH0)
图14 UART波特率除数寄存器(UBRDIV0)
上述寄存器是和UART通信相关的寄存器,使用简单的无FIFO,无自动流控AFC时,设置如下:
UFCON0 = 0x00; //不使用FIFO
UMCON0 = 0x00; //不使用流控
UBRDIV0 = 26; //波特率为115200,PCLK=50MHz
UBRDIV0 = 53; //波特率为57600,PCLK=50MHz
UBRDIV0 = 12; //波特率为57600,PCLK=12MHz
UTXH0和URXH0分别是数据发送和接收寄存器,发送数据时通过轮询方式判断发送状态寄存器的状态,当可以发送数据时,执行UTXH0寄存器写入操作,接收数据时,以轮询方式检测接收状态寄存器状态,当有数据到达时,读取URXH0寄存器里的数据即可取得串口数据。
1 #define TXD0READY (1<<2) //发送数据状态OK 2 #define RXD0READY (1) //接收数据状态OK 3 4 /* UART串口单个字符打印函数 */ 5 extern void putc(unsigned char c) 6 { 7 while( ! (UTRSTAT0 & TXD0READY) ); 8 UTXH0 = c; 9 } 10 11 /* UART串口接受单个字符函数 */ 12 extern unsigned char getc(void) 13 { 14 while( ! (UTRSTAT0 & RXD0READY) ); 15 return URXH0; 16 }