1.UART结构
UART2输入时钟为PLL1_SYSCLK2,PLL1_SYSCLK2是PLL1_SYSCLK1的2分频,PLL1_SYSCLK1的频率默认为456MHz,PLL时钟树如图:
(指南P130)
(指南P131)
定义UART2输入时钟频率如下:
1 // 时钟 2 #define SYSCLK_1_FREQ (456000000) 3 #define SYSCLK_2_FREQ (SYSCLK_1_FREQ/2) 4 #define UART_2_FREQ (SYSCLK_2_FREQ)
主函数如下:
1 intmain(void) 2 { 3 // 外设使能配置 4 PSCInit(); 5 6 // GPIO 管脚复用配置 7 GPIOBankPinMuxSet(); 8 9 // DSP 中断初始化 10 InterruptInit(); 11 12 // UART 初始化 13 UARTInit(); 14 15 // UART 中断初始化 16 UARTInterruptInit(); 17 18 // 主循环 19 for(;;) 20 { 21 22 } 23 }
其中,GPIOBankPinMuxSet();函数如下:
1 voidGPIOBankPinMuxSet(void) 2 { 3 // UART2 禁用流控 4 UARTPinMuxSetup(2, FALSE); 5 }
UARTPinMuxSetup函数为创龙开发板特有的配置函数,该函数位于starterware/application/platform目录工程中的UART.C文件里。该函数对系统配置模块0(System Configuration Module 0,SYSCFG0)的引脚复用控制寄存器4(Pin Multiplexing Control 4 Register,PINMUX4,地址值为0x01C1 4130h)进行设置,将GP1[2]脚功能设置为UART2_TXD,该脚作为UART2的发送脚,将GP1[3]脚功能设置为UART2_RXD,该脚作为UART2的接收脚。PINMUX4寄存器地址及其各字段含义如下所示,UARTPinMuxSetup附在图后。
(指南P204)
(指南P225)
(指南P225)
(指南P226)
1 /****************************************************************************/ 2 /* */ 3 /* 管脚复用配置 */ 4 /* */ 5 /****************************************************************************/ 6 voidUARTPinMuxSetup(unsignedint instanceNum, unsignedint modemCtrlChoice) 7 { 8 unsignedint svPinMuxRtsCts = 0; 9 unsignedint svPinMuxTxdRxd = 0; 10 11 if(0 == instanceNum) 12 { 13 if(TRUE == modemCtrlChoice) 14 { 15 svPinMuxRtsCts = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(3)) & \ 16 ~(SYSCFG_PINMUX3_PINMUX3_27_24 | \ 17 SYSCFG_PINMUX3_PINMUX3_31_28)); 18 19 HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(3)) = \ 20 (PINMUX3_UART0_CTS_ENABLE | \ 21 PINMUX3_UART0_RTS_ENABLE | \ 22 svPinMuxRtsCts); 23 } 24 25 svPinMuxTxdRxd = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(3)) & \ 26 ~(SYSCFG_PINMUX3_PINMUX3_23_20 | \ 27 SYSCFG_PINMUX3_PINMUX3_19_16)); 28 29 HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(3)) = \ 30 (PINMUX3_UART0_TXD_ENABLE | \ 31 PINMUX3_UART0_RXD_ENABLE | \ 32 svPinMuxTxdRxd); 33 } 34 35 elseif(1 == instanceNum) 36 { 37 if(TRUE == modemCtrlChoice) 38 { 39 svPinMuxRtsCts = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) & \ 40 ~(SYSCFG_PINMUX0_PINMUX0_23_20 | \ 41 SYSCFG_PINMUX0_PINMUX0_19_16)); 42 43 HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) = \ 44 (PINMUX0_UART1_CTS_ENABLE | \ 45 PINMUX0_UART1_RTS_ENABLE | \ 46 svPinMuxRtsCts); 47 } 48 49 svPinMuxTxdRxd = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) & \ 50 ~(SYSCFG_PINMUX4_PINMUX4_31_28 | \ 51 SYSCFG_PINMUX4_PINMUX4_27_24)); 52 53 HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) = \ 54 (PINMUX4_UART1_TXD_ENABLE | \ 55 PINMUX4_UART1_RXD_ENABLE | \ 56 svPinMuxTxdRxd); 57 } 58 59 elseif(2 == instanceNum) 60 { 61 62 if(TRUE == modemCtrlChoice) 63 { 64 svPinMuxRtsCts = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) & \ 65 ~(SYSCFG_PINMUX0_PINMUX0_31_28 | \ 66 SYSCFG_PINMUX0_PINMUX0_27_24)); 67 68 HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) = \ 69 (PINMUX0_UART2_CTS_ENABLE | \ 70 PINMUX0_UART2_RTS_ENABLE | \ 71 svPinMuxRtsCts); 72 } 73 74 svPinMuxTxdRxd = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) & \ 75 ~(SYSCFG_PINMUX4_PINMUX4_23_20 | \ 76 SYSCFG_PINMUX4_PINMUX4_19_16)); 77 78 HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) = \ 79 (PINMUX4_UART2_TXD_ENABLE | \ 80 PINMUX4_UART2_RXD_ENABLE | \ 81 svPinMuxTxdRxd); 82 83 } 84 85 else 86 { 87 88 } 89 }
管脚复用配置完成后,就要对UART进行初始化了。初始化参考步骤如图所示:
(指南P1427)
UART初始化函数中,首先配置UART2的参数。设置UART2波特率为115200bps,UART2模块的内存地址为0x01D0D000,波特率在UART模块的DLL(Divisor LSB Latch)和DLH(Divisor MSB Latch)寄存器中设置,DLL存储Divisor的低8位,DLH存储Divisor的高8位,在波特发生器(Baud generator)中对UART输入时钟进行分频,分频系数为Divisor,从而产生波特时钟(baud clock,BCLK)。波特时钟BCLK的值应为波特率的16倍或13倍,具体是16倍还是13倍取决于过采样率,如果是16倍过采样,则16个波特时钟才完成1bit的传输,如果是13倍过采样则是13个波特时钟。计算公式及UART时钟发生框图如下所示:
(指南P1419)
设置UART的帧格式为数据位8,停止位1,无校验位,帧格式在流控制LCR(Line Control Register)中定义。设置过采样模式(Over-Sampling Mode,OSM)为16倍过采样,采样模式在MDR(Mode Definition Register)寄存器中定义。
(手册P23)
(指南P1430)
完成UART2初始化后,就开始使能UART2。使能UART2,只要设置PWREMU_MGMT寄存器的UTRST、URRST和FREE3位就行了。
(指南P1447)
然后使能接收和发送FIFO,在FCR寄存器中对相应位进行设置。通过使能FIFO,可以减少软件对CPU的过度开销,因为FIFO可以对要发送或接收的字符进行缓存(buffering),所以不用每接收或者发送一个字节就中断一次这样频繁地打断CPU的进程,只有当FIFO满了之后才通知CPU,一次把所有的数据处理完,大大提高了CPU的工作效率。
使能FIFO后还要设置FIFO级别,接收器FIFO可以设置为1字节满,4字节满,8字节满或14字节满共4个级别。
(指南P1436)
这样,UART初始化就完成了,UART初始化代码如下:
1 voidUARTInit(void) 2 { 3 // 配置 UART2 参数 4 // 波特率 115200 数据位 8 停止位 1 无校验位 5 UARTConfigSetExpClk(SOC_UART_2_REGS, UART_2_FREQ, BAUD_115200, 6 UART_WORDL_8BITS, UART_OVER_SAMP_RATE_16); 7 // 使能 UART2 8 UARTEnable(SOC_UART_2_REGS); 9 10 // 使能接收 / 发送 FIFO 11 UARTFIFOEnable(SOC_UART_2_REGS); 12 13 // 设置 FIFO 级别 14 UARTFIFOLevelSet(SOC_UART_2_REGS, UART_RX_TRIG_LEVEL_1); 15 }