开关矩阵SWM
在前面第一个示例中,有一个更改引脚功能的函数Ext_Osc,后来由于MDK的支持,在可视化的sytem_LPC82x.c文件中把振荡修改为外部方式,就把它给取消了。其实在LPC824中,更改引脚功能是一项常用功能,不仅如此,甚至还可以把某些功能重新分配到任何一根非电源的引脚上,下面就来详细讨论一下这些功能。
在讨论之前,先要明确几个相关概念。其一,LPC824的引脚(见前面的引脚功能图)是以GPIO0_x的形式来描述的,即GPIO0_x是固定不动的。以GPIO0_13端口为例,它在HVQFN33的封装中位于芯片第1号引脚上,这是固定不变的,即不能再把GPIO_13端口分配到其他芯片引脚上,所以一般就以GPIO_13的名称来描述其所在引脚,而不以芯片第1号引脚来描述。这样做的好处是,即使改变了芯片封装(即芯片物理引脚变化了),相对的GPIO_13引脚名称是不变的,即引脚名称的描述与芯片封装无关。其二,在默认情况下,LPC824芯片第1号引脚上不仅有GPIO_13功能,还有复合有ADC_10功能,即第10路A/D转换的输入端。这样在GPIO_13引脚上就集成了两种功能,只不过在默认情况下是GPIO_13的通用输入/输出功能。再次强调一下,这里严格的描述应该是,在LPC824的GPIO_13引脚上还复用有ADC_10功能,而不要描述为,在LPC824芯片的第1号引脚上有GPIO_13和ADC_10两种功能,即不描述到具体的物理引脚上(虽然两种描述是一回事)。同时,ADC_10在GPIO_13引脚上也属于固定功能,即它也不能再被分配到其他引脚上去。因此,要确定这类具有“固定功能”引脚上的具体功能,就需要操作一个寄存器来进行选择,这个寄存器就是引脚使能寄存器PINENABLE0。这在前面的函数Ext_Osc中,也是通过操作这个寄存器,把GPIO0_8、GPIO0_9引脚配置为XTALIN、XTALOUT引脚的。其三,在LPC824中还有一些功能并没有分配到具体的引脚上,或即使分配了也可能还需要重新调整到其他引脚。比如前面时钟输出示例中的时钟输出引脚CLKOUT,在默认状态下并没有为它分配物理引脚,这样时钟信号就输不出来,而在示例中是把CLKOUT分配到了引脚GPIO0_24上,因此可以通过示波器测量GPIO0_24引脚来观察时钟波形。类似CLKOUT这样的,可分配到除电源以外的所有引脚的功能,被称为“可移动功能”,操作的寄存器是引脚分配寄存器PINASSIGN0。总结一下,“固定功能”的引脚功能只能切换不能移动,“可移动功能”可以任意分配引脚(电源引脚除外)。
在LPC824中,实现上述引脚功能的模块称为开关矩阵(SWITCH MATRIX),它是芯片的重要组成部分,除电源外的29个GPIO引脚都由开关矩阵SWM来分配功能,如下图所示。
从上图中可以看出,基本上所有的功能(如:USART、SPI、I2C、ADC……)都通过开关矩阵和外部的29根引脚相连接,具体怎么分配由开关矩阵中的两个寄存器PINENABLE0和PINASSIGN0来共同确定。下面就来详细讨论这两个寄存器的用法,先来看引脚使能寄存器PINENABLE0,下表给出了它的全部位结构,其字节地址为0x4000C1C0。
(1)第0位为PIO0_0引脚上的功能使能控制位,值为0时使能引脚上的ACMP_I1功能,值为1时禁止ACMP_I1功能(即恢复为PIO0_0功能),默认为PIO0_0功能。
(2)第1位为PIO0_1引脚上的功能使能控制位,值为0时使能引脚上的ACMP_I2功能,值为1时禁止ACMP_I2功能(即恢复为PIO0_1功能),默认为PIO0_1功能。
(3)第2位为PIO0_14引脚上的功能使能控制位,值为0时使能引脚上的ACMP_I3功能,值为1时禁止ACMP_I3功能(即恢复为PIO0_14功能),默认为PIO0_14功能。
(4)第3位为PIO0_23引脚上的功能使能控制位,值为0时使能引脚上的ACMP_I4功能,值为1时禁止ACMP_I4功能(即恢复为PIO0_23功能),默认为PIO0_23功能。
(5)第4位为PIO0_3引脚上的功能使能控制位,值为0时使能引脚上的SWCLK功能,值为1时禁止SWCLK功能(即恢复为PIO0_3功能),默认为SWCLK功能。
(6)第5位为PIO0_2引脚上的功能使能控制位,值为0时使能引脚上的SWDIO功能,值为1时禁止SWDIO功能(即恢复为PIO0_2功能),默认为SWDIO功能。
(7)第6位为PIO0_8引脚上的功能使能控制位,值为0时使能引脚上的XTALIN功能,值为1时禁止XTALIN功能(即恢复为PIO0_8功能),默认为PIO0_8功能。
(8)第7位为PIO0_9引脚上的功能使能控制位,值为0时使能引脚上的XTALOUT功能,值为1时禁止XTALOUT功能(即恢复为PIO0_9功能),默认为PIO0_9功能。
(9)第8位为PIO0_5引脚上的功能使能控制位,值为0时使能引脚上的RESETN功能,值为1时禁止RESETN功能(即恢复为PIO0_5功能),默认为RESETN功能。
(10)第9位为PIO0_1引脚上的功能使能控制位,值为0时使能引脚上的CLKIN功能,值为1时禁止CLKIN功能(即恢复为PIO0_1功能),默认为PIO0_1功能。
(11)第10位为PIO0_6引脚上的功能使能控制位,值为0时使能引脚上的VDDCMP功能,值为1时禁止VDDCMP功能(即恢复为PIO0_6功能),默认为PIO0_6功能。
(12)第11位为PIO0_11引脚上的功能使能控制位,值为0时使能引脚上的I2C0_SDA功能,值为1时禁止I2C0_SDA功能(即恢复为PIO0_11功能),默认为PIO0_11功能。
(13)第12位为PIO0_10引脚上的功能使能控制位,值为0时使能引脚上的I2C0_SCL功能,值为1时禁止I2C0_SCL功能(即恢复为PIO0_10功能),默认为PIO0_10功能。
(14)第13位为PIO0_7引脚上的功能使能控制位,值为0时使能引脚上的ADC_0功能,值为1时禁止ADC_0功能(即恢复为PIO0_7功能),默认为PIO0_7功能。
(15)第14位为PIO0_6引脚上的功能使能控制位,值为0时使能引脚上的ADC_1功能,值为1时禁止ADC_1功能(即恢复为PIO0_6功能),默认为PIO0_6功能。
(16)第15位为PIO0_14引脚上的功能使能控制位,值为0时使能引脚上的ADC_2功能,值为1时禁止ADC_2功能(即恢复为PIO0_14功能),默认为PIO0_14功能。
(17)第16位为PIO0_23引脚上的功能使能控制位,值为0时使能引脚上的ADC_3功能,值为1时禁止ADC_3功能(即恢复为PIO0_23功能),默认为PIO0_23功能。
(18)第17位为PIO0_22引脚上的功能使能控制位,值为0时使能引脚上的ADC_4功能,值为1时禁止ADC_4功能(即恢复为PIO0_22功能),默认为PIO0_22功能。
(19)第18位为PIO0_21引脚上的功能使能控制位,值为0时使能引脚上的ADC_5功能,值为1时禁止ADC_5功能(即恢复为PIO0_21功能),默认为PIO0_21功能。
(20)第19位为PIO0_20引脚上的功能使能控制位,值为0时使能引脚上的ADC_6功能,值为1时禁止ADC_6功能(即恢复为PIO0_20功能),默认为PIO0_20功能。
(21)第20位为PIO0_19引脚上的功能使能控制位,值为0时使能引脚上的ADC_7功能,值为1时禁止ADC_7功能(即恢复为PIO0_19功能),默认为PIO0_19功能。
(22)第21位为PIO0_18引脚上的功能使能控制位,值为0时使能引脚上的ADC_8功能,值为1时禁止ADC_8功能(即恢复为PIO0_18功能),默认为PIO0_18功能。
(23)第22位为PIO0_17引脚上的功能使能控制位,值为0时使能引脚上的ADC_9功能,值为1时禁止ADC_9功能(即恢复为PIO0_17功能),默认为PIO0_17功能。
(24)第23位为PIO0_13引脚上的功能使能控制位,值为0时使能引脚上的ADC_10功能,值为1时禁止ADC_10功能(即恢复为PIO0_13功能),默认为PIO0_13功能。
(25)第24位为PIO0_4引脚上的功能使能控制位,值为0时使能引脚上的ADC_11功能,值为1时禁止ADC_11功能(即恢复为PIO0_4功能),默认为PIO0_4功能。
(26)第25到31位为保留位。
从上表中可以看出,在“固定功能”中每根引脚上具有两种功能,一种是GPIO即通用输入/输出功能,另一种是附加功能。这两种功能通过寄存器PINENABLE0中相应的控制实现切换。在默认状态下(即复位后),只有PIO0_2、PIO0_3及PIO0_5等三根引脚上的功能为附加功能,其余引脚均为GPIO功能。 原因也很简单,PIO0_2、PIO0_3及PIO0_5引脚上的附加功能为芯片提供程序下载及外部复位功能,这在芯片初始状态下是必须的。而其他引脚全部为GPIO引脚,以尽可能多的提供出通用输入/输出功能。
接下来讨论“可移动功能”,下表给出的是LPC824中所有“可移动功能”及其分配寄存器。
从上表中可以看出,在LPC824中,串口USART0~2、SPI0~1、SCT、I2C1~3、ADC_PINTRIG0~1、ACMP_O、CLKOUT及GPIO_INT_BMAT等功能均为可移动功能,分配它们的寄存器从PINASSIGN0到PINASSIGN11一共12个。下面就以其中的一个来进行讨论,其他的可参照使用。
下表给出了引脚分配寄存器PINASSIGN0的全部位结构,其字节地址为0x4000C000。
(1)第0到7位为串口USART0中的发送端TXD分配引脚,可选范围从PIO0_0到PIO0_28一共29根引脚,默认为未分配状态。
(2)第8到15位为串口USART0中的接收端RXD分配引脚,可选范围从PIO0_0到PIO0_28一共29根引脚,默认为未分配状态。
(3)第16到23位为串口USART0中的请求发送端RTS分配引脚,可选范围从PIO0_0到PIO0_28一共29根引脚,默认为未分配状态。
(4)第24到31位为串口USART0中的清除发送端CTS分配引脚,可选范围从PIO0_0到PIO0_28一共29根引脚,默认为未分配状态。
从上表可以看出,PINASSIGN0寄存器就是用来为串口USART0的各个功能端口来分配引脚的,每一个功能端口都可以分配到29根引脚中的任意一根上,默认状态下是不分配的,即复位后LPC824的29根引脚上没有USART0的功能,要使用USART0功能必须先进行引脚分配。但需要说明一点,USART0的功能虽然在芯片复位后是没有被分配的,但由于在ISP模式下芯片是需要通过USART0的收发端口来下载程序的,所以在ISP模式下,USART0的TXD和RXD端口分别被固定在了引脚PIO0_1和PIO0_0上,但仅限于ISP模式下(即复位前PIO0_12引脚接地)。
需要强调一点,当某个引脚上被切换为附加功能时,是不能把“可移动功能”分配到该引脚上的,也就是说,“可移动功能”只能分配给具有GPIO功能的引脚。例如,要把USART0的TXD端口分配到GPIO0_8引脚上,但若此时GPIO0_8引脚为XTALIN功能,就不能进行分配,而需要先通过操作引脚使能寄存器PINENABLE0,把XTALIN功能禁用后(即恢复GPIO0_8引脚后),才能再操作引脚分配寄存器PINASSIGN0,把TXD端口分配给GPIO0_8引脚,具体过程如下图所示。
此外,还需要说明的是,当“可移动功能”被分配给某个引脚时,该引脚的GPIO功能将会被禁用。另外,如果“可移动功能”是输入方向的,可以把多个输入连接到同一根引脚上,但如果是输出方向或双向的,则只能分配一个功能到一根引脚上。最后再强调一点,SWM的时钟默认是开启的,在配置完PINENABLE0及PINASSIGN0寄存器后,为了节约功耗,可在SYSAHBCLKCTRL寄存器中把SWM时钟禁用。