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. 开始位+数据位奇偶校验位+停止位
这里的帧可以画图表示:
至于一帧数据到底是怎么设置的,可以使用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) //初始化函数
{undefined
//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) //发送一个字符函数
{undefined
/* 等待,直到发送缓冲区中的数据已经全部发送出去 */
while(!(rUTRSTAT0 & (1<<2)));
/* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */
rUTXH0 = c;
}
unsigned char get_c(void) //接收函数
{undefined
/* 等待,直到接收缓冲区中的有数据 */
while(!(rUTRSTAT0 & 1));
/* 直接读取URXH0寄存器,即可获得接收到的数据 */
returnrURXH0;
}
上一篇:二、2440 裸机 中断原理分析
下一篇:s3c2440 移植linux内核 添加网卡支持 yaffs2文件系统支持
推荐帖子
- 变频技术小知识
- 1、什么是变频器? 变频器是利用电力半导体器件的通断作用将工频电源变换为另一频率的电能控制装置。2、PWM和PAM的不同点是什么?PWM是英文PulseWidthModulation(脉冲宽度调制)缩写,按一定规律改变脉冲列的脉冲宽度,以调节输出量和波形的一种调值方式。PAM是英文PulseAmplitudeModulation(脉冲幅度调制)缩写,是按一定规律改变脉冲列的脉冲幅度,以调节输出量值和波形的一种调制方式。3、电压型与电流型有什么不同? 变频器的主电路
- ZYXWVU 电源技术
- IAR给430下载完程序为什么调试不了
- 李嘉辉 Microchip MCU
- CCS5.1程序设计中的问题
- CCS5.1中如何添加头文件、源文件、命令文件等的默认搜索路径,让程序编辑中能自动识别这些文件(而不是需要一个一个的添加),请问哪位大神能帮我解决一下CCS5.1程序设计中的问题这种方法我试了,添加头文件可以,可是其他.c和.asm和.cmd的文件却不能自动添加进去,请问这个问题应该怎么处理回复沙发qinkaiabc的帖子
- xyc2006 DSP 与 ARM 处理器
- EEWORLD大学堂----ARM 2014 多媒体研讨会
- ARM2014多媒体研讨会:https://training.eeworld.com.cn/course/2152ARM2014多媒体研讨会EEWORLD大学堂----ARM2014多媒体研讨会
- chenyy 单片机
- AltiumDesigner怎样为4层板输出Gerber文件
- 这里的GP1和GP2是负片,需要特殊设置吗?生成的gerber文件我看到中间的电层和地层还是原来的样子厂家在做的时候这层应该不是这样的吧?或者怎么才能让GND层用正常的方式显示呢(圆点处是透光的,其它地方是铜皮)?AltiumDesigner怎样为4层板输出Gerber文件AD生成Gerber文件时把该选的层选上即可,不用考虑负片正片其实GTSTopSolder顶层阻焊层,有人也称为防锡层,其实也是负片正确预览Gerber文件好像要修改扩展名 你是说厂家可以从
- littleshrimp PCB设计
- 求助(汇编语言实现数码显示)
- 有一个12位的AD转换器,将模拟量转换为数字量,同时要用四个七段数码管将这个模拟量显示出来.单位机用的是8位的89C51,要用汇编语言实现,该怎么做呢?麻烦谁会做,给解释一下.求助(汇编语言实现数码显示)找一下AD574的例子,网上会有的Re:求助(汇编语言实现数码显示)参考一下,也许有用的$扫描方式的二位数计时器01ORG00H02MOVR0,#00H;设置起始计数值为0003AGAIN:MOVR3,#25H;在R3中设置LOOP的循环次数04LOOP
- maolv1983 单片机
设计资源 培训 开发板 精华推荐
- MC33269 800mA 可调输出、低压降稳压器的典型应用,用于电池后备电源
- LT3761EMSE-1 40W SEPIC LED 驱动器的典型应用电路
- 用于开/关控制应用的 AM2G-0515SZ 15V 2 瓦 DC-DC 转换器的典型应用
- 库房安全管理系统
- DC814A-E,使用 LTC6905-100 17MHz 至 170MHz 固定频率硅振荡器的演示板
- stm32F411 system
- AD8626ARMZ-REEL精密放大器的典型应用电路,用于显示直流误差的光电二极管模型
- MPC555CME: MPC555评估板
- LT3955 的典型应用 - 具有内部 PWM 发生器的 60VIN LED 转换器
- 基于MAX5941B PWM控制器的用电(PD)模块参考设计