S3C2440UART之FIFO
一、基础知识
S3C2440有3个独立的串口,每一个都可以利用DMA和中断方式操作。每个包含2个64字节FIFO,一个收,一个发。非FIFO模式相当于FIFO模式的一个寄存器缓冲模式。每一个UART有7种状态,overrun错误,校验错误,帧错误,断点,接收缓冲区准备好,发送缓冲区为空,发送移位寄存器为空。当接收移位寄存器中的数据传给FIFO的时候,且接收的数据触发了Rx FIFO的阀值,Rx中断产生了。发送器中FIFO的还未发得数据到达Tx FIFO阀值的时候,Tx中断产生了。(我觉得应该理解为:发送器中FIFO发送结束,即为空的时候产生中断。)
二、例程:串口0接收中断,接收FIFO出发深度16byte
1 /**************串口0寄存器初始化****************/ 2 void UART0_INIT(int pclk,int baud) 3 { 4 int i; 5 if(pclk == 0) 6 pclk = PCLK; 7 rUFCON0 = 0x21; //UART channel 0 FIFO control register, FIFO disable 8 rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable 9 rULCON0 = 0x3; 10 rUCON0 = 0x385; // Control register 11 rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 ); 12 }
1 /************中断处理函数********************/ 2 char buff[30]; 3 char *ps = buff; 4 int i = 0; 5 6 DisableSubIrq(BIT_SUB_RXD0); //关闭串口中断 7 i = (rUFSTAT0&0x1f); 8 Uart_Printf("count is %x\n",i); 9 if(rSUBSRCPND & BIT_SUB_RXD0) //接收中断 10 { 11 while(((rUFSTAT0&0x1f)>0)) 12 { 13 *ps++ = rURXH0; 14 } 15 } 16 *ps++ = '\0'; 17 i = (rUFSTAT0&0x1f); 18 Uart_Printf("count is %x\n",i); 19 Uart_Printf("buff is %s\n",buff); 20 ClearSubPending(BIT_SUB_RXD0); //恢复中断 21 ClearPending(BIT_UART0); 22 EnableIrq(BIT_UART0); 23 EnableSubIrq(BIT_SUB_RXD0);
三、运行结果及分析
1.当一次接收的字符数小于FIFO-RX的触发深度时(本例中RX触发深度为16byte),若超过3个时钟周期依旧没有检测到字符则同样会因为超时而发起中断请求。
2.当一次发送的字符数在16byte-29byte之间时,串口只会发起一次中断请求。例程中,检测到串口发起中断后程序会从FIFO中取走所有的字符,猜测还未等到剩下的字符发起超时中断,其已被取走,因而不会发起超时中断,当然若不取走则会发生超时中断(猜测:单片机虽设定为16字节发起中断,但为了不影响后面数据的接收,留了一定大小的缓冲区,在串口发起中断请求到处理器正式响应之前继续接收下面的字符)。
3.当一次发送的字符数大于29byte时,产生两次以上的中断。