#define _ISR_STARTADDRESS 0x33ffff00#define pISR_UART0 (*(unsigned *)(_ISR_STARTADDRESS+0x90))#define U32 unsigned int #define rGPBCON (*(volatile unsigned *)0x56000010) //Port B control#define rGPBDAT (*(volatile unsigned *)0x56000014) //Port B data#define rGPBUP (*(volatile unsigned *)0x56000018) //Pull-up control B #define rGPHCON (*(volatile unsigned *)0x56000070) //Port H control//#define rGPHDAT (*(volatile unsigned *)0x56000074) //Port H data#define rGPHUP (*(volatile unsigned *)0x56000078) //Pull-up control H #define rULCON0 (*(volatile unsigned *)0x50000000) //UART 0 Line control#define rUCON0 (*(volatile unsigned *)0x50000004) //UART 0 Control#define rUFCON0 (*(volatile unsigned *)0x50000008) //UART 0 FIFO control#define rUMCON0 (*(volatile unsigned *)0x5000000c) //UART 0 Modem control#define rUTRSTAT0 (*(volatile unsigned *)0x50000010) //UART 0 Tx/Rx status#define rUERSTAT0 (*(volatile unsigned *)0x50000014) //UART 0 Rx error status#define rUFSTAT0 (*(volatile unsigned *)0x50000018) //UART 0 FIFO status#define rUMSTAT0 (*(volatile unsigned *)0x5000001c) //UART 0 Modem status#define rUBRDIV0 (*(volatile unsigned *)0x50000028) //UART 0 Baud rate divisor //little endian#define rUTXH0 (*(volatile unsigned char *)0x50000020) //UART 0 Transmission Hold#define rURXH0 (*(volatile unsigned char *)0x50000024) //UART 0 Receive buffer #define rSRCPND (*(volatile unsigned *)0x4a000000) //Interrupt request status#define rINTMSK (*(volatile unsigned *)0x4a000008) //Interrupt mask control#define rINTPND (*(volatile unsigned *)0x4a000010) //Interrupt request status#define rSUBSRCPND (*(volatile unsigned *)0x4a000018) //Sub source pending#define rINTSUBMSK (*(volatile unsigned *)0x4a00001c) //Interrupt sub mask void __irq uartISP(void){char ch;rSUBSRCPND |= 0x3;rSRCPND = 0x1<<28;rINTPND = 0x1<<28; if(rUTRSTAT0 & 1) //接收数据处理部分{ch = rURXH0; //接收字节数据 if(ch==0x55)rGPBDAT = ~0x61; //亮两个LEDelserUTXH0 = ch; //发送字节数据}else //发送数据处理部分{rGPBDAT = ~0x1e1; //亮4个LED} } void Main(void) {rGPBCON = 0x015551;rGPBUP = 0x7ff; rGPBDAT = 0x1e0;rGPHCON = 0x00faaa; rGPHUP = 0x7ff;rULCON0 = 0x3; rUCON0 = 0x5; rUFCON0 = 0;rUMCON0 = 0;rUBRDIV0 = 26; rSRCPND = 0x1<<28; rSUBSRCPND = 0x3;rINTPND = 0x1<<28; rINTSUBMSK = ~(0x3); //打开UART0发送和接收中断屏蔽 rINTMSK = ~(0x1<<28); //打开UART0中断屏蔽 pISR_UART0 = (U32)uartISP; while(1); } 最后还要强调几点关于非FIFO模式下UART中断的一些注意事项: 1. 对于s3c2440来说,接收数据是被动的,发送数据是主动的,因此一般来说,接收数据用中断方式,发送数据用查询方式较好;2. 在中断方式下,当接收到数据时,尽管可能该数据无用,但也一定要读取它,否则下次再接收数据时,不会再引起中断,因为接收数据缓存器被上次接收到的数据所霸占,只要没有读取它,它就永远在那里;3. 由于UART中断涉及到SUBSRCPND寄存器,因此在中断处理程序中不仅要清SRCPND寄存器,还要清SUBSRCPND寄存器,它们的顺序一定是先清SUBSRCPND寄存器,再清SRCPND寄存器,否则就会引起一个中断两次响应的问题。因为是否中断由SRCPND寄存器决定,而SRCPND寄存器的相关状态位由SUBSRCPND寄存器决定,如果先清SRCPND寄存器,而还没有清SUBSRCPND寄存器的话,SRCPND寄存器的相关位还是会被置1,而一旦被置1,则一定还会引起中断。本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhaocj/archive/2010/03/10/5364412.aspx s3c2440串口文档s3c2440的UART提供了三个同步串行IO口,第一个串口都可以使用中断模式和DMA模式,换句话说就是UART可以产生一个中断或者是DMA请求使数据在CPU和UART之间进行传递。UART在系统时钟下可以支持最高位传送为115.2K BPS.如果一个外部设备能过UEXTCLK为UART提供时钟,UART可以达到更高的速度。每个UART通道包括两个64字节的FIFO作为接收数据和发送数据使用。 s3c2440的UART包括可编程的波特率,红外收发,一个或者两个停止位。5位,6位,7位,8位的数据位和校验检测。每一个UART包括一个波特率产生器,发送器,接收器和一个控制单元。波特率产生器可以使用PCLK,FCLK/n或者UEXTCLK之一控制。发送器和接收器包含64字节的FIFO和一个数据移位器。数据先写到FIFO中然后再拷贝到发送移位器中,然后再移位发送通过数据针TxDn。在些期间远端发送过来的数据通过针RxDn进入到移位器中再拷贝到接收器的FIFO中去。属性--RxD0,TxD0,RxD1,TxD1,RxD2,和TxD2都可使用基于DMA的和中断的操作--UART通道0,1,和2都拥有IrDA和64字节的FIFO--UART通道0和1:nRTS0,nCTS0,nRTS1,nCTS1--收发数据时支持握手 UART的操作UART的操作,包括数据传输,数据接收,产生中断,波特率的产生回环模式,红外模式和自动流控制。数据传输发送的数据帧是可以改变的,它由起始位5~8个数据位一个可选的校验位和1~2个停止位构成。这些都可以通过策略控制器ULCONn设置。数据发送器也可以产生一个停止标志,它可以强迫串口输出逻辑0达一帧的时间,它在一个字传输完成以后阻塞了停止信号的传送。然后继续传输数据到Tx FIFO中。数据接收与数据的发送相似,接收到的数据帧也是可以修改的。它包括一个起始位,五到八个数据位,一个可选的校验位和一到两个停止位。接收器可检测到覆盖错误,校验错误,帧错误和终止的情况。每一种情况都会设置一个错误标志位。--覆盖错误产生的情况是这样的,新数据覆盖掉了还没有来的及取出的旧数据,也就是说接收数据速度快于取出的速度导致一部分数据还没有取出就被新的数据盖掉了。--校验错误是指接收到的数据经过计算与校验位不符。--帧错误是指收到的数据不含有停止位。--终止的情况是指RxDn端保持在逻辑零的状态时间长于一帧数据传送的时间。--接收超时的情况是指在可以接收3个字的时间里没有收到任何的数据,并且在FIFO模式时Rx的FIFO非空。自动流量控制(AFC)S3C2440的UART 0和UART 1通过信号nRTS和nCTS支持自动流量控制。在这种情况下,它可以连接到外部的UARTs中去。如果用户想把串口连接到Modem上,需要关闭寄存器UMCONn的自动流控制位,并通过软件控制nRTS信号线。在AFC模式下,nRTS依赖于接收器,nCTS信号控制着发送器的操作。UART的数据发送器只在nCTS信号使能的时候才把数据传送到FIFO中(在AFC模式下nCTS的意思是其它UART的FIFO已经准备好接收数据了)。在UART开始接收数据之前,需要先根据数据接收器的FIFO剩余空间设置nRTS的值,如果剩余空间大于32字节则nRTS使能,否则如果剩余空间小于32字节则nRTS关闭(在AFC模式下,nRTS的作用就是表示它所控制的接收器的FIFO准备好接收数据了)。 UART 2不支持AFC功能,因为S3C2440没有nRTS2和nCTS2非自动流量控制的例子(通过软件控制信号nRTS和nCTS)接收器对FIFO的操作1.选择接收模式(中断模式或者DMA模式)2.检查寄存器UFSTATn中Rx FIFO的值,如果这个值小于32,用户必须设置UMCONn[0]为“1”(使能nRTS),如果值大于32,用户必须设置UMCONn[0]的值为“0”(关闭nRTS)3.重复第2步。发送器对FIFO的操作1.选择一个发送模式(中断或者DMA)2.检查UMSTATn[0]的值,如果为“1”(使能nCTS),用户写数据到Tx FIFO寄存器S3C2440的每个UART都有七个状态:覆盖错误,校验错误,帧错误,终止,接收缓冲区已准备好,发送缓冲区空,和发送移位器空。所有这些都对应到UART的状态寄存器中(UTRSTATn/UERSTATn).覆盖错误,校验错误,帧错误和终止属于接收错误,它们中的任何一个都可以引起一个叫“receive error status”的中断请求。如果这个中断请求在寄存器UCONn中的使能位被置为“1”,并且当这个请求被处理时通过读取UERSTSATn的值可知引起这个中断的信号,也就是找到是哪种错误引起的中断。 FIFO模式与非FIFO模式在FIFO模式下,接收器从接收移位器中收数据然后写入到FIFO中,如果收到数据的个数达到Rx FIFO的触发点,且在寄存器UCONn中的接收模式被设置成“1”(中断或者轮询模式),将会产生一个Rx中断。在非FIFO模式下,不论是中断模式还是轮询模式,只要有数据从接收移位寄存器中传送到数据接收保持寄存器中都会产生一个Rx中断。在FIFO模式下,如果发送模式在控制寄存器UCONn中被设置成中断模式或者轮询模式,发送数据要从发送FIFO中传送到发送移位器中,如果在FIFO中剩余的数据个数达到了Tx FIFO的触发点,就是产生一个Tx中断。在非FIFO模式下,发送的数据从发送保持寄存器传送到发送移位器中后会产生一个Tx中断,这个也是要求数据发送方送方式为中断模式或者是轮询模式。如果在控制寄存器中数据发送方式和接收方式被设置成DMA模式,那么和上面的情况一样,只是产生的Rx和Tx中断被换成了DMA请求。 UART的错误FIFOUART有一个“错误状态”FIFO组,它对应着接收器的FIFO,它指示在接收器的FIFO中哪个数据错误了。只有在接收器中错误数据被读取的时候才会产生错误中断。在从URXHn读取数据的时候同时读取UERSTATn寄存器的值就知道这个数据哪里错了,什么错误。例子假设UART顺序接收了A B C D E这五个数据,其中接收B的时候发生了帧错误,接收D的时候发生了校验错误。在接收B的时候不会产生“错误中断”,在接收“D”的时候也不会产生“错误中断”。当读取B数据和D数据的时候“错误中断”才会产生。 波特率的产生ART的波特率发生器为串行数据的发送与接收提供时钟,波特率发生器的“源时钟”可以是S3C2440的内部系统时钟也可以是外部时钟(UEXTCLK),换句话说就是通过设置UCONn的“时钟”选项可以改变除数因子。波特率是由“源时钟”(PCLK,FCLK/n UEXTCLK)除以16和一个除数因子。公式是这样的:除数因子=(整型)(“源时钟”除以波特率乘以16)减1除数因子UBRDIVn的取值范围是1~2^16-1,但当使用外部时钟UEXTCLK时它却可以等于0.(这个外部时钟要低于PCLK)例如:如果波特率是115200bps,UART的时钟是40MHz,除数因子UBRDIVn是UBRDIVn = (int)(40000000 / (115200 x 16) ) -1= (int)(21.7) -1 [round to the nearest whole number]= 22 -1 = 21波特率的错误容忍度UART的帧错误必须低于1.87% |