003_<ARM9从裸机到Linux操作系统>____裸机篇__S3C2440的UART编程

一、概述

 

S3C2440通用异步接收和发送(UART)提供了三路的不同异步串行I/O端口,每一个端口可以被配置为中断模式或者DMA模式 。也就是说UART可以产生中断或者DMA请求来在CPUUART之间传输数据。UART可以支持高达115.2K波特率使用系统时钟。如果一个外部设备为UART提供UEXTCLK,那么UART可以运行在更高的速度上。每个UART通道包含了两个64-byteFIFO队列用于接收器和发送器。

 

S3C2440AUART包含了可编程的波特率,红外(IR)接收发送,1个或2个结束位的嵌入,5-bit6-bit7-bit或者8-bit的数据宽度和奇偶校验。

 

每一个UART包含了一个波特率产生器(buad-rategenerator),发送器(transmitter),接收器(receiver)和一个控制单元(controlunit),如下图显示:

波特率产生器可以由PCLK,FCLK/n或者UEXTCLK(external input clock)来提供时钟。发送器和接收器包含了64-byteFIFO队列和数据移位器(data shifters)。数据写入FIFO然后在开始传输之前被拷贝到发送数据移位器。然后数据被移位并一位一位地输出通过发送数据管脚(TxDn)。同理,接收数据被移位通过从接收器数据管脚(RxDn),然后把数据从接收数据移位器里拷贝到FIFO

 

二、数据发送(data transmission

 

用于发送出去的数据帧是可编程的,由一个start位,58的数据位,一个可选的奇偶校验位和12的结束位组成。发送器也可以产生终止条件,通过迫使串行输出逻辑‘0’状态持续一个帧的传输时间。这个阻塞传输终止信号是在当前传输字被完成传输完成之后生效的。再终止信号传输之后,发送器连续不断地发送数据到Tx FIFO(Non-FIFI模式下的Tx holding register(发送保持寄存器) )

 

三、数据接收(data reception

 

就像发送数据一样,接收数据帧也是可编程的。由一个start位,58的数据位,一个可选的奇偶校验位和12个结束位。接收器可以检测接收泛滥错误(overrun error),奇偶校验错误(parity error),帧错误(frame error)和终止条件(break condition),通过设置错误标志。

 

·overrun error指示了数据已经覆写了还没有被读出去的数据。

·parity error指示了接收器检测到一个奇偶错误。

·frame error指示了接收数据没有一个有效的结束位。

·break condition指示了RxDn输入管脚被钳住在逻辑‘0’状态持续了多于一个帧传输时间。

·当接收器在3word时间里(这个间隔根据字位长的设置)没有接收到数据并且在FIFO模式下的Rx FIFO不为空则产生接收超时条件。

 

四、自动流控制(Auto flow controlAFC))

 

S3C2440AUART0UART1支持自动流控通过使用nRTSnCTS信号。在这种情况下,可以链接外部的UARTs。假如用户需要连接一个UART到一个modem,则需要取消自动流控位通过配置UMCONn寄存器并且通过软件来控制nRTS的信号。

 

AFC模式下,nRTS依赖于接收器的条件和nCTS信号控制发送器的运行。UART的发送器只当nCTS信号被激活(AFC模式下,nCTS信号意味另一个UARTFIFO已经准备好接收数据了)才发送数据到另一个UARTFIFO里。在UART接收数据的时候,当接收FIFO有大于32-byte的空闲空间时nRTS必须被激活 ,在接收FIFO的空闲空间小于32-byte(在AFC模式下,nRTS信号意味自己的接收FIFO准备好接收数据)时nRTS必须被取消激活。

UART2不支持AFC功能。

 

五、没有使用自动流控的例子(需要软件控制nRTSnCTS

 

1)使用FIFO的接收操作

 

·选择接收模式(interrupt or DMA mode

·检查UFSTATn寄存器里的RX FIFO计数值 。假如这个值小于32,用户需要设置UMCONn[0]为‘1’(激活nRTS),如果等于或者大于32,用户需要设置这个值为‘0’(使nRTS无效)

·一直重复步骤2

 

2)使用FIFO的发送操作

 

·选择发送模式(interrupt or DMA mode

·检查UMSTATn[0]的值。如果该值为‘1’(nCTS被激活),用户可以写数据到Tx FIFO寄存器

 

六、RS-232C接口

 

如果用户想要连接UARTmodem接口,nRTSnCTSnDSRnDTRDCDnRI信号需要被用到。在这种情况下,用户可以使用软件控制这些信号通过通用I/O端口来模拟时序 ,因为AFC不支持RS-232C接口。

 

七、interrupt/DMA

 

每个UART7个状态(Tx/Rx/Error)信号。所有这些都通过UART状态寄存器(UTRSTATn/UERSTATn.

 

overrun errorparity errorframe error or break condition都属于接收错误状态。每一个error都引起接收错误中断请求,前提是在控制寄存器UCONn里的receive-error-status-interrupt-enable被设置为‘1’。当receive-error-status-interrupt-request被检测到,这个信号会导致这个请求可以被识别到通过读取UERSTSTn的值。

 

当接收器在FIFO模式下 ,把数据从接收数据移位器传递到接收FIFO寄存器并且接收数据数已经达到了Rx FIFO的触发水平时,Rx中断被产生,如果在控制寄存器(UCONn)的接收模式被选择为‘1’(interrupt request orpolling mode)。在Non-FIFO模式下,数据从接收移位器传递数据到接收保持寄存器将导致Rx 中断(under the interrupt request and polling mode

 

当发送器把数据从发送FIFO寄存器传递给发送数据移位器并且发送FIFO里的数据数达到Tx FIFO的触发水平,Tx中断被产生(如果在控制寄存器里的发送模式选择为interrupt request orpolling mode)。在Non-FIFO模式下,从发送保持寄存器发送数据到发送移位器将引起Tx中断(under the interrupt request and polling mode

 

如果控制寄存器里的接收模式和发送模式选择了DMAn请求模式,那么DMAn请求将替代上面的Rx or Tx中断。

 

八、UART error status FIFO

 

UART除了有Rx FIFO寄存器外还拥有错误状态FIFO。错误状态FIFO指明了在FIFO寄存器里哪个数据,接收错误了。错误中断只在那个发生错误的数据准备被读出时被下达。通过读取带有错误标志的URXHnUERSTATn来清除错误状态FIFO

 

如下图所示:

注:

·假设UART Rx FIFO接收到A,B,C,DE字符序列并且帧错误发生在接收'B',奇偶校验错误出现在接收'D' 

·事实上,UART接收错误并不会产生任何错误中断,因为产生错误的字符还没有被读出。错误中断只在错误字符被读出时才会产生。

 

 

 

九、波特率的产生

 

每个UART的波特率产生器都提供了串行时钟给收发器。而用于波特率产生器的源时钟则是采用了S3C2440A的内部系统时钟或者UEXTCLK。也就是说,这个是可选的,通过配置UCONn的时钟选择。通过分离源时钟(PCLK,FCLK/n or UEXTCLK)(通过配置UARTbaud-rate divisor registerUBRDIVn)来产生波特率时钟。公式如下:

UDRDIVn int)(UART clock /buad rate * 16))- 1

其中UART clock : PCLKFCLK/n or UEXTCLK,并且UBRDIVn只能是1(2^16-1),但是在使用比PCLK小的UEXTCLK时是可以设置为0的(bypass mode)。

 

比如,如果波特率选择为115200bpsUART时钟是40MHzUBRDIVn计算如下:

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

int)(21.7-1 = 22 - 1 = 21

 

十、baud-rate error tolerance

 

·UART帧错误必须小于1.87%(3/160)

·tUPCLK = UBRDIVn + 1* 16 * 1Frame/PCLK tUPCLK : 真正的UART时钟

·tUEXACKT = 1 Frame / baud-rate tUEXACT:理想UART时钟

·UART error = tUPCLK - tUEXACT) / tUEXACT * 100%

 

 

 

注意:

 

·1Frame = start bit + data bit + parity bit + stop bit

·在特殊条件下,我们能够支持的UART波特率高达921.6K bps 。比如,当PCLK=60MHz,我们能够使用921K bps(只要满足UARTerror 小于 1.69%

 

十一、回送模式(Loop Mode

 

S3C2440UART提供一个测试模式叫做Loopback mode,来帮助隔离掉通信线路的错误。这个模式下在结构上使RXDTXD相连。在个模式下,发送数据给接收器通过RXD。这个特性允许处理器来验证内部发送和接收数据的每个SIO通道部分。这个模式可以选择通过设置UART控制寄存器(UCONn)的loopback bit

 

十二、红外线模式(InfraredIRmode

 

S3c2440aD UART模块支持红外线发送和接收 , 可以通过设置UART线路控制寄存器(ULCONn)的infrared-mode bit。下图演示了IR模式的执行。

注:

IR发送模式下,发送脉冲来至波特率的3/16,正常的串行发送波特率(当发送数据位为0时);在IR接收模式下,接收器必须检测3/16的脉冲周期来识别处一个0值(参考以下帧时序图)

 

1.相关原理图

2.相关寄存器介绍与配置

1)与管脚相关

 

①GPHCON

 

注:

配置成UART0功能:

GPHCON |= 10 10 10 10b(还要在GPHUP里把管脚禁止上拉)

2)与中断相关


上传图片好麻烦,跟以前相关的这里就不贴了

3)与UART0相关

①ULCON0

注:

Infrared Mode :选择普通模式

Parity Mode : 选择不执行奇偶校验

Number of stop :选择1个结束位

Word length :8-bits字长

ULCON0 = 0x03

②UBRDIV0和UCON0

注:

UBRDIVn = (int)(UART clock /(baud rate * 16)) - 1,因为下面我们选择了PCLK作为UARTclock。所以UBRDIV0=(int)PCLK/(baudrate*16)) - 1。其中PCLK=101.25MHz,波特率选择115200

UBRDIV0=(int)( 101250000/(115200*16) ) - 1 = 54.

选择UBRDIV0= 0x36

注:

Clock selection :时钟源选择,选择PCLK,根据上个定时器实验得知PCLK使用101.25MHz。00b

注:

脉冲触发:指的是在Tx buffer从有数据跳变为空时(对于接收模式来说,则是Rx buffer从空跳变为有数据)触发一次边沿中断,之后即使为空,但是没有这个跳变是不会触发中断的(Non-FIFO)。对于使用FIFO来说,一旦到达Tx/Rx FIFO的触发水平时才产生一个边沿中断,其它时候都不会触发中断。

水平触发:指的是只要Tx buffer为空(对于接收模式来说,则是只要Rx buffer有数据)则一直产生中断请求(电平中断)。对于使用FIFO来说,只要是高于(接收模式)/低于(发送模式)或等于触发水平就一直产生中断(电平中断)。

①如果发送中断采用了脉冲触发,在发送中断处理里执行太长时间的情况下,导致下个脉冲中断请求在中断处理函数里产生了,那么如果请求中断请求位是在后面清除的,则会引起下个脉冲中断请求被清除了而无法再次进入发送中断(因为数据已经被发送出去了,则不会再达到触发水平(FIFO)或者从从有数据到空的跳变(non-FIFO))。而如果是采用水平触发则不会发生这种情况,因为只要是空的(non-FIFO)或低于等于触发水平(FIFO),即便被清除了请求位,还是会产生请求,但是这样会连绵不断的触发中断。

②如果接收中断采用了脉冲触发,在接收中断处理里执行太长时间的情况下,也会导致下一个脉冲中断请求在中断处理函数里产生了,那么如果请求中断请求位是在后面清除的,则会引起下个脉冲中断请求被清除了而无法再次进入发送中断(因为之前的数据还没被取出,则不会再达到触发水平(FIFO)或者从空到有数据的跳变(non-FIFO))。而如果是采用水平触发则不会发生这种情况,因为只要有数据(non-FIFO)或高于等于触发水平(FIFO),即便被清除了请求位,还是会产生请求,但是这样会连绵不断的触发中断。

举个栗子:

①只使能发送中断,选择FIFO,触发水平为empty,在发送中断里发送一个字节,延迟3秒,这段时间足够让Tx FIFO里从一个数据跳变到empty(2),即发送中断请求(1)在中断处理函数里产生了。

·使用脉冲触发:退出中断处理函数清除了中断请求,也就把(1)给清掉了,进不了发送中断无法给数据,并且Tx FIFO一直为空(无法出现(2)) , 因此不再产生中断。

·使用水平触发:退出中断处理函数清除了中断请求,也把(1)给清掉了,但是只要是低于或等于empty在FIFO里,则电平中断还会产生,能够再次进入中断。

②只使能接收中断,选择FIFO,触发水平为1-byte,PC机上发一个字节触发中断,在接收中断里接收一个字节,延迟3秒,在这段时间里再发1个字节,这样会有一个从empty到1-byte的跳变(2),这样就在中断服务函数里产生了中断请求,即接收中断请求(1)在中断处理函数里产生了。

·使用脉冲触发:退出中断处理函数清除了中断请求,也就把(1)给清掉了,进不了接收中断无法取出数据,并且Rx FIFO一直1-byte数据(无法出现(2)) , 因此不再产生中断。

·使用水平触发:退出中断处理函数清除了中断请求,也把(1)给清掉了,但是只要是高于或等于1-byte数据在FIFO里,则电平中断还会产生,能够再次进入中断。

经测试成立。

Tx interrupt type :保险点选择水平触发就行了,不过这个我们只在需要发送数据再打开,发送完数据再关闭,这样就防止老是进入中断。1b

Rx interrupt type :同理 ,选择水平触发就好了,只要有数据就进入中断处理数据。1b

Rx timeout enable :选择禁止。0b

Rx error status interrupt enable :禁止接收错误状态中断。0b

Loopback mode :选择普通模式。0b

Send break signal :选择正常传输。0b

注:

Transmit mode :选择中断请求或者轮询模式。01b

Receive mode :选择中断模式或者轮询模式。01b

UCON0 = 0x305

③UFCON0

注:

Tx FIFO trigger level :选择emply,只有在FIFO到达空了才会触发中断。00b

Rx FIFO trigger level :选择1-bype,这样只要接收到1个字节就直接进入中断取出处理。00b

Tx FIFO reset :选择normal。0b

Rx FIFO reset :选择normal。0b

FIFO enable :使能FIFO。1b

UFCON0 = 0x01

④UMCON0

注:

AFC flow control:不使能自动流控。0b

Request to send:不使能自动流控,这个位也不需要用到

初始化时:UMCON0 = 0;

⑤UTRSTAT0

注:只读

Transmitter empty:当发送缓冲寄存器(FIFO)已经没有有效数据可以发送并且发送数据移位器为空。该域会被置为‘1’。

Transmit buffser empty:当发送缓冲寄存器空时被置为‘1’。(只针对于Non-FIFO,Tx FIFO模式需要检测UFSTAT寄存器的count 位和Tx FIFO Full 位)

Receive buffer data ready:当接收缓冲寄存器包含了从PXDn端口接收到的有效数据时被设置为‘1’。(只针对于Non-FIFO,Rx FIFO模式需要检测UFSTAT寄存器的count位和Rx FIFO Full 位)

⑥UERSTAT0

注:(当这个状态寄存器被读取时会自动清零

Break detect:当一个break 信号被接收到了这个位会被置‘1’。

Frame Error :当一个帧错误在接收操作期间产生时被置‘1’。

Parity error :当一个奇偶校验错误在接收期间产生时被置‘1’。

Overrun error:当一个overrun错误在接收期间产生时被置‘1’。

⑦UFSTAT0

注:

Tx FIFO full :当发送FIFO在发送期间满了,这个位会被置‘1’。

Tx FIFO count :Tx FIFO里的data数。

Rx FIFO Full :当接收FIFO在接收期间满了,这个位会被置‘1’。

Rx FIFO count :Rx FIFO里的data数。

⑧UMSTAT0

注:

Delta CTS:指明了nCTS输入到S3C2440A状态是否改变了知道该位被CPU读取了才自动清零。

Clear to send:要发送数据时需要检查该位是否有效,有效才可以写数据到Tx FIFO。

这两个都用在自动流控功能里。如果双方都不使用自动流控。这个也可以不管。

⑨UTXH0(UART0发送缓冲寄存器)

注:

TXDATA0:存放用户要发送的数据

⑩URXH0(UART0接收缓冲寄存器)

注:

(当overrun error发生时,URXH0必须被读出,否则,下一个接收到的数据也会造成overrun error尽管UERSTAT0的overrun位已经被清除了)

RXDATA:存放接收到的数据

3.流程图设计

①主流程图

②中断处理子程序

③中断服务子函数

4.程序设计

****************************************************************************************************

UART实验:

****************************************************************************************************/

#include<s3c2440.h>

void uart0_init()

 {

 GPHCON|=0xa0;//GPH2,GPH3用作TXD0RXD0

GPHUP=0x0c;//使用上拉电阻

ULCON0=0x03;//设置模特率115200、数据格式位:8个数据位没有流量控制

UCON0=0x05;//设置为查询方式,UART的时钟源为PCLK

UFCON0=0x00;//不适用FIFO

UMCON0=0x00;//不适用流控

UBRDIV0=((50000000)/(115200*16)-1);//波特率为115200

}

/************************发送一个字符****************************/

void putc(unsigned char c)

{

while(!(UTRSTAT0&(1<<2)))

UTXH0=c;

}

/************************接受一个字符****************************/

unsigned char getc(void)

{

while(!(UTRSTAT0&1));

return URXH0;

}

 

 

void main()

 

{

uart0_init();

putc('a');

while(1);

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值