<1>
由于UART的波特率设置与时钟有关,此文设置FCLK:HCLK:PCLK=1 : 2 : 4,FCLK=200MHZ,遂先介绍时钟的设置。
通常认为上电复位后PLL是不稳定的。因此在软件重新配置PLLCON之前Fin代替MPLL直接供给Fclk。即便用户不希望复位之后改变PLLCON的数值,用户还是要用软件写入相同的数值到PLLCON寄存器中。
按照MDK4.22中启动代码的设置来说明以下设置。
MPLL,UPLL根据公式即可算出,这里的MPS最后算出的Fclk=200Mhz。PCLK也就是50Mhz了。
注意到HDIVN这里设置为0x01,不为0,那么Fclk != Hclk,要将fast mode转为异步模式,不然的话,Fclk相当于Pclk了。
由于MDK自带的启动代码没有这部分代码,所以自己加以修改了这部分。
FAST_TO_ASYN如果勾选的话,会选中
IF ASYN_SETUP <> 0
MRC p15, 0, r1, c1, c0, 0
ORR r1, r1, #0xc0000000
MCR p15, 0, r1, c1, c0, 0
ENDIF
这样就可以配置成自己想要设置的时钟了。
关于串口的知识
3个独立的串口,每一个都可以利用DMA和中断方式操作。每个包含2个64字节FIFO,一个接,一个发。
非FIFO模式相当于FIFO模式的一个寄存器缓冲模式。
每一个UART有7种状态,overrun错误,校验错误,帧错误,断点,接收缓冲区准备好,发送缓冲区为空,发送移位寄存器为空。钱4个被认为是接收错误状态,每一个都可以引起接收错误状态中断请求,前提是UCONn中设置了receive-error-status-interrupt-request=1。
当接收移位寄存器中的数据传给FIFO的时候,且接收的数据触发了Rx FIFO的阀值,Rx中断产生了。
发送器中FIFO的还未发得数据到达Tx FIFO阀值的时候,Tx中断产生了。
程序要点:
本程序首先完成基本的UART0的配置,比如TXO RXO的管脚配置,这可以在启动文件里配置完成,接着ULCON0配置,UCON0配置,UFCON0配置,UMCON0配置,UBRDIV0配置,INTSUBMSK打开相应位,INTMSK打开相应位。
中断程序里,接收和发都会引起UART0中断,在里面要加以区分,是接还是发引起。接设置FIFO16字节触发,脉冲模式;发为0字节触发,电平模式。
注意到一上电,UART0配置完成后,就会触发发中断,因为发设置为0电平模式触发,所以为了避免无缘无故的触发,需要在某些时机下,禁止中断。
功能:在串口上输入16字节,包括回车,然后会把输入的字符回显在串口终端上。
程序代码:
uart.c
/* * PC<----->2440UART0 */ #include "S3C2440.h" #include "uart.h" static u8 string[512] = {0,0}; static u8 data_is_ready = 0; void init_uart0(void) { rULCON0 = 0x03; rUCON0 = (0x05) | (1<<9); //15---12 11-10 9 8 7 6 5 4 3-2 1-0 //not pclk/n pclk Tlevel Rpulse timeout disable rx error int disable loop dis break dis int or poll int or poll rUFCON0 = (0x0<<6) | (0x02<<4) | (0x01<<0); //0 0 1 1 0 0 0 1 //Tx trigger level = 0 Rx trigger level = 16bytes FIFO enable=1 rUMCON0 = 0x0; rUBRDIV0 = UART_BRDIV; rINTSUBMSK &= ~BIT_SUB_RXD0; rINTMSK &= ~BIT_UART0; pHandleUART0 = UART0_Handle; } void __irq UART0_Handle(void) { u8* ps = string; if(rSUBSRCPND&0x01){ rINTSUBMSK |= BIT_SUB_RXD0; while(((rUFSTAT0&0x1f)>0)) *ps++ = RdURXH0_L; data_is_ready = 1; rSUBSRCPND = BIT_SUB_RXD0; } else if(rSUBSRCPND&0x02) { int i; rINTSUBMSK |= BIT_SUB_TXD0; while((!(rUFSTAT0&(1<<14))) && (*ps != '\r')) { WrUTXH0_L(*ps++); for(i=0; i<100;i++); } data_is_ready = 0; rSUBSRCPND = BIT_SUB_TXD0; } rSRCPND = BIT_UART0; rINTPND = BIT_UART0; if(data_is_ready) rINTSUBMSK &= ~(BIT_SUB_TXD0); else rINTSUBMSK &= ~(BIT_SUB_RXD0); }
main.c
#include "S3C2440.h" #include "uart.h" int main(void) { rGPBDAT |= (0xf<<5); init_uart0(); while(1); }
经测试可以完成功能。
上一篇:S3C2440在MDK4.22下使用printf向串口打印调试
下一篇:ARMLinux s3c2440 之UART分析一
推荐阅读最新更新时间:2024-03-16 14:56