四、s3c2440 裸机开发 通用异步收发器UARN

四、通用异步收发器UARN


原文地址 http://blog.csdn.net/woshidahuaidan2011/article/details/51137047

by jaosn Email: woshidahuaidan2011@hotmail.com


 UART(Universal AsynchronousReceiver/Transmitter,通用异步接收/发送装置)用于异步通信,可以实现全双工发送和接收。2440有三个UART:UART0,UART1,UART2其结构图如下所示:


通过上图可以看到UART包含baud-rate generator波特率发生器,transmitter发送器,receiver 接收器and a control unit控制单元。在UART使用FIFO模式的时候,其中发送器和接收器分别有一个大小为64字节的发送缓存器寄存器和接收缓存寄存器FIFO(先进先出),通过上图还可以看到,假如不使用FIFO模式,接收器分别使用的发送保存寄存器和接收保存寄存器;还可以看到,图中波特率产生器会受到时钟源的影响,UART可有三个时钟源以供选择,分别为PCLK,FCLK/n还有外部时钟UEXTCLK。

对于波特率产生器,首先要提到UBRDIVn(n为0,1,2下面雷同),可以通过该寄存器设置波特率,设置的公式如下:

UBRDIVn=(int)(UARTclock / (buad ratex 16) ) –1

其中UART clock正如上面说的,可以选择PCLK, FCLK/n or UEXTCLK

UBRDIVn可以取值为0到2^16-1,在旁路模式下(bypass mode),该寄存器可以设置为0,该寄存器图为:


此寄存器不用多说明,直接填写数字就可以。

假设要设置的波特率为115200,UART的时钟UART clock为40M的话,那么:

UBRDIVn =(int)(40000000 / (115200 x 16) ) -1

= (int)(21.7) -1 [round to the nearestwhole number]

=22 -1 = 21

可以看到,上面的计算取整之后将会出现误差,这里的误差允许范围为1.87%,误差计算方式为:

tUPCLK = (UBRDIVn + 1)x 16 x 1Frame / PCLK        tUPCLK:   实际UART Clock
tUEXACT = 1Frame / baud-rate                       tUEXACT:  理想UART Clock

UART error = (tUPCLK – tUEXACT) / tUEXACTx 100%

其中1Frame = start bit + data bit + parity bit + stop bit. 开始位+数据位奇偶校验位+停止位

这里的帧可以画图表示:

start bit(1位)

data bit(5-8位)

parity bit(1位)

stop bit(1或2位)

 

 

 

 

 

 

 

 

 

 

 

 

至于一帧数据到底是怎么设置的,可以使用ULCONn寄存器,以ULCON0为例:


ULCON0【1:0】设置数据位的格式,可以设置成5到8位

ULCON0【2】设置停止位,1位或者两位停止位

ULCON0【5:3】设置校验模式,0xx表示无校验

                                                           100表示奇校验

                            101表示偶校验

                            101表示发送数据强制设置为1,接受数据检测是否为1

                            101表示发送数据强制设置为0,接受数据检测是否为0

ULCON0【6】设置模式,0表示正常模式,1表示红外模式

 

通过ULCONn设置帧的传输格式是最基本设置,设置完帧格式后就可以设置UART时钟源和一些模式设置,这个设计的寄存器为UCONn:

 


这里,UCONn主要是设置一写发送或者接收数据模式、中断触发形式和UART的时钟选择设置。看一下每一位具体含义:

UCONn【1:0】选择如何接收缓存器读取数据 00表示禁止接收数据

                                                                                        01表示中断接收或者查询法接收

                                                                                        10表示DMA0请求(UART0独有)

                                                                                               DMA3请求(UART2独有)                                                                                                                 11表示DMA1请求(UART1独有)

UCONn【3:2】选择如何发送缓存器发送数据   00表示禁止发送数据

                                                                                        01表示中断发送或者查询法发送

                                                                                        10表示DMA0请求(UART0独有)

                                                                                               DMA3请求(UART2独有)                                                                                                                 11表示DMA1请求(UART1独有)

UCONn【4】 设置此位,UART会在一帧的时间内发送一个break信号,发送完之后改位自动清除。

UCONn【5】 自循环模式,这种模式仅用于测试,该位设置为1可以,在内部,RX和TX会连接起来。

UCONn【6】设置接收错误状态接收使能,此位设置为1时,当发生比如帧错误,溢出错误时将产生中断。

UCONn【7】当使用UART的FIFO的时,此位设置为1时,当接收超时时,会触发中断。

UCONn【8】接收中断设置,设置为1表示电平触发,设置为0表示脉冲触发,在FIFO模式时,当FIFO的值达到设置的阈值会触发中断,在非FIFO模式时,有一个数据便触发中断。

UCONn【9】发送中断设置,设置为1表示电平触发,设置为0表示脉冲触发,在FIFO模式时,当FIFO的值达到设置的阈值会触发中断,在非FIFO模式时,有一个数据便触发中断。

UCONn【11:10】UART时钟选择: 00/10 PCLK  01外部时钟UEXTCLK   11  FCLK/n

UCONn【15:12】选择FCLK/n模式的时候,用来确定n的具体数值。下面详细介绍一下:

n的值要受到UCON0【15:12】、UCON1【15:12】和UCON2【14:12】共同决定的,且当其中的一个设置为非0时,其余两个必须设置为0,其中要注意的是:

UCON2[15]起到决定性因素,是FCLK/n的使能位。

n的值设置方式为:

当n的范围为7到21时,UART时钟=FCLK/( UCON0【15:12】的设定值+6)

当n的范围为22到36时,UART时钟=FCLK/(UCON1【15:12】的设定值+21)

当n的范围为37到43时,UART时钟=FCLK/(UCON2【14:12】的设定值+36)

 

通过阅读上面的寄存器的含义结合自己实际的需求就可以完成其模式的选择即使时钟的配置,刚才有有提到UART发送和接收都可以使用一款缓冲区FIFO,这里介绍一下UART的FIFO,控制FIFO的寄存器UFCONn:


这里仍以UFCON0为例:

UFCON0【0】FIFO使能位,决定是否使用FIFO

UFCON0【1】接收FIFO复位位,设置为1,将自动清除接收FIFO的内容

UFCON0【2】发送FIFO复位位,设置为1,将自动清除发送FIFO的内容

UFCON0【5:4】接收FIFO触发阈值设定

UFCON0【7:6】发送FIFO触发阈值设定

 

UART的FIFO总体来说比较简单,结合前面所讲解的帧格式,时钟,基本就设置的差不多了,通过上面的基本设置就可以使用UART,但是,2440为了是数据在传输的过程中尽量避免数据的丢失,也有有关自动流控制AFC(Auto Flow Control)的寄存器UMCONn,介绍该寄存器之前,需要对流控制做有关的说明:

数据在两个串口之间传输时,常常会出现丢失数据的现象,或者两台计算机的处理速度不同,如台式机与单片机之间的通讯,接收端数据缓冲区已满,则此时继续发送来的数据就会丢失。现在我们在网络上通过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字符后就立即开始发送数据。一般可以从设备配套源程序中找到发送的是什么字符。 当软件里用了流控制时,应做详细的说明,如何接线,如何应用。应该注意,若传输的是二进制数据,标志字符也有可能在数据流中出现而引起误操作,这是软件流控制的缺陷,而硬件流控制不会有这个问题。

接下来看下2440自动流控制有关的寄存器UMCONn:


通过下面的注释可以注意到只有UART0和UART1拥有AFC功能,下面对寄存器的位做出简要说明

UMCONn【0】:设置为1使能nRTS(请求发送),但是假如使能使能AFC功能,该位是无效的,该位的值是2440自动设置的

UMCONn【1:3】:保留位,必须为0

UMCONn【1】:AFC使能位,设置为1使能AFC

UMCONn【5:7】:保留位,必须为0

与之对应的状态寄存器是UMSTATn,主要是读取一些请求发送的状态信息,这里不再详细说明,具体查阅手册。

设置部分已经介绍完毕,通过上面的设置,即可完整的完成通信。但是当数据发送或者接收的时候,用户往往想知道是否发送完毕,或者已经发送了多少还差多少可以发送完毕等,也不比如在接收数据的时候,用户要知道已经接收到了多少数据,是否已经接收完毕或者还差多少才可以接收完毕。所以我们还需要几个状态寄存器来了解UART的运行状态:

 

UTSTATn寄存器用于表明收发的一些状态,是一些只读寄存器:

UTSTATn【0】收到数据该位自动置1,当使用FIFO,应该配合查询检测UFSTAT寄存器

UTSTATn【1】当发送缓冲区没有数据时该位置1,当使用FIFO,应该配合查询检测UFSTAT寄存器

UTSTATn【2】当发送缓存器没有数据且最后一个数据发送完毕的时候该为置1.

刚才有提到UFSTATn寄存器,看下下他的作用:


UFSTATn寄存器是使用FIFO需要注意的:

UFSTATn【5:0】接收FIFO缓存器的数据的数目

UFSTATn【6】当接收FIFO缓存器的满了之后该位自动为置1

UFSTATn【13:8】发送FIFO缓存器的数据的数目

UFSTATn【14】当发送FIFO缓存器的满了之后该位自动为置

 

还有一个错误状态寄存器UERSTATn需要需要注意:


UERSTATn【0】在接受数据时,发生溢出错误是该位置1

UERSTATn【1】在接受数据时,有校验错误则置1

UERSTATn【2】在接受数据时,有帧错误则置1

UERSTATn【3】在接受数据时,到BREAK信号的时候则置1

注意,当读取该寄存器时,UERSTATn寄存器将自动清零。

寄存器UFSTATn和寄存器UERSTATn就像一个显示器一样,通过这两个显示器,你可以知道UART的收发数据状态及其FIFO的状态。

到现在为止,有关UART的原理及其寄存器已经介绍完毕,一切设置完毕后就可接收或者发送数据了,接收和发送比较简单,只需要向着UTXHn 和URXHn写入数据或者读取数据就可以(都是以byte为单位):

UTXHn:将要发送的数据发到此寄存器,UART会把数据放到发送缓冲区,自动发送出去,数值0到255

URXHn :从该寄存器读取数据,数值0到255

 

现在对串口接收实例进行总结:

1、  设置相关的引脚为UART功能的引脚 可以通过GPnCON寄存器来设置,一般情况下要使能上拉电阻功能以使端口稳定,通过GPnUP设置上拉使能

2、  设置UART的数据帧格式 可通过ULCONn来设置

3、  设置UART的时钟源,及其发送接收方式  可通过UCONn来设置

4、  对于有关FIFO的设置 通过UFCONn来设置

5、  设置是否使用自动流控 可通过UMCONn来设置

6、  设置UART的波特率 UBRDIVn

 

给出一个初始化的例子:

voiduart0_init(void)

void uart0_init(void) //初始化函数

{

 

          //1、设置相关的引脚为UART功能的引脚可以通过GPnCON寄存器来设置,一般情况下要使能上拉电阻功能以使端口稳定,通过GPnUP设置上拉使能

           //   TXD0=GPH2 RXD0=GPH3

           rGPHCON &=~(3<<4);

           rGPHCON|=(2<<4);  //TXD0

           rGPHCON&=~(3<<6);

           rGPHCON|=(2<<6);  //TXD0

           rGPHUP  &=~(3<<2);//使能上拉

 

           //2设置UART的数据帧格式可通过ULCONn来设置

//8个数据位1位停止位无校验位正常模式

           rULCON0 |= 0x03 ;

           //3设置UART的时钟源,及其发送接收方式 可通过UCONn来设置

          rUCON0 |=(1|(1<<2));//设置查询或者中断接收,查询或者中断发送,时钟源为PCLK其余采用默认值

 

           //4对于有关FIFO的设置通过UFCONn来设置

 

           rUFCON0 &=~1;//不使用FIFO

 

           //5设置是否使用自动流控可通过UMCONn来设置

           rUMCON0 &=~(1<<4);//不使用AFC

 

           //6设置UART的波特率  UBRDIVn

           rUBRDIV0=(int)( PCLK_DATA /( BUAD_RATE * 16) )-1;//PCLK=50m 波特率115200

}

 

 

 

void send_c(unsigned char c)  //发送一个字符函数

{

    /* 等待,直到发送缓冲区中的数据已经全部发送出去 */

    while(!(rUTRSTAT0 & (1<<2)));

    /* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */

    rUTXH0 = c;

}

 

unsigned char get_c(void) //接收函数

{

    /* 等待,直到接收缓冲区中的有数据 */

    while(!(rUTRSTAT0 & 1));

   

    /* 直接读取URXH0寄存器,即可获得接收到的数据 */

    returnrURXH0;

}

参考:http://blog.csdn.net/g1036583997/article/details/12717297

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值