微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > LPC1114通用输入/输出端口(GPIO)

LPC1114通用输入/输出端口(GPIO)

时间:11-13 来源:互联网 点击:

<7”,其实就是“P0 =P0| 0b10000000”,这就可以看出,它先要把P0的值读出来,然后进行修改(和0b10000000相与),最后再把结果写回P0去。而“方法二”就简单多了,直接访问地址为0b10000000的单元就行了。下面详细来讨论方法二是如何实现位操作的。

为了实现“方法二”的位操作,在LPC1114中引入了一个新的概念——屏蔽(MASK)。它利用一个14位的结构来描述屏蔽操作,只有在屏蔽结构中值为1的位所对应的端口引脚值才会生效。例如要改变端口第7个引脚的电平,那么在这个端口所对应的屏蔽结构中,与第7个引脚对应的屏蔽位的值必须为1才行。同时要注意,屏蔽位并不是与端口位置一一对应的,而是屏蔽结构整体“左移”了两位再来对应!由于端口引脚数量为12,屏蔽结构又整体“左移”两位,所以它才需要用一个14位的结构来描述。据此,那么刚才第7个引脚所对应的屏蔽位应该是第9位。要改变第7个引脚的电平,屏蔽结构中的第9位的值要是1才行。此过程可用下图来描述,至于为何屏蔽结构要“左移”两位,后面会进行详细讨论。

在上图中,第一行表示的就是屏蔽结构,可见它是一个14位的结构,并且低两位没有用。第二行表示要写入到端口引脚上的值,如果第一行的屏蔽值都为1,那么第二行的这12个值就会被原封不动地写到12位端口引脚上去。第三行表示的就是端口引脚上的值,可见由于屏蔽结构中只有第9位的值为1,所以对应到要写入的数据第7位的值(1)就写到了端口引脚的第7位上去了(第7脚输出高电平),而端口引脚的其它位则保持不变(不论要写入的数据中对应的位是何值),这就是屏蔽结构的作用。前面讨论过,这个屏蔽结构涵盖了12位的所有组合状态,所以从全部不屏蔽(0x000)到全部屏蔽(0xFFF),都包含在了其中。由此可以看出,当屏蔽结构的值为全部屏蔽(0xFFF)时,就是要写入的数据值全部都关联(输入或输出)到端口引脚,这也就是前面提到的“方法一”的做法,相当于直接写数据到端口。所以说“方法二”包含了“方法一”。

从上图还可以看出,GPIODATA的地址是GPIO基址+屏蔽地址(偏移地址)。在LPC1114中共有4组GPIO端口,它们的基址分别是:port0为0x50000000;port1为0x50010000;port2为0x50020000;port3为0x50030000。而每组端口都有自己的屏蔽地址,4组GPIO基址加上各自的屏蔽地址后就是:port0为0x50000000~0x50003FFC;port1为0x50010000~0x50013FFC;port2为0x50020000~0x50023FFC;port3为0x50030000~0x50033FFC。每组都有4096个32位的单元。

接下来讨论为何屏蔽结构要“左移”两位再来对应。关于这一点,即便在管方文档中也没有给出解释。但通过观察可以看出,虽然屏蔽结构只用了14位来描述,但由于处理器本身是32位结构的,所以其实每个屏蔽结构本身的长度还是32位的,只不过它只用了低14位就足够了。换句话说,一个屏蔽结构要占用4个字节的地址。而全部(4096个)屏蔽结构就要占用4×4096个地址,因为地址是从0算起的,所以整个屏蔽结构所占用的地址是4×4096-1=16383个,也即十六进制的0x3FFC个。对应上面的“GPIO寄存器分布情况表”会发现,这个值正好是GPIODATA寄存器地址偏移的最大值。那这两个之间会有什么关系呢?其实只能证明一点,在引入了屏蔽结构的概念后,屏蔽结构就是GPIODATA寄存器!更确切的说是地址为0x000~0x3FF8这段的GPIODATA寄存器(因为最后一个地址为0x3FFC的屏蔽结构是全部不屏蔽(值全为1),可以认为它无屏蔽作用,所以一般把它当作端口寄存器用(即“方法一”))。

这时再回到“GPIO寄存器分布情况表”上来看,第一行的GPIODATA的地址为0x000~0x3FF8,它是实际的4095个屏蔽结构,每个占用4个字节地址,使用时对应“方法二”;第二行的GPIODATA的地址为0x3FFC,它相当于端口寄存器,共占用4个字节地址,使用时对应“方法一”。但两者只能选其一,不能两种方法都同时用!

由于C语言中的共用体(或称联合体)就具有地址空间复用的特点,所以利用共用体来定义GPIODATA是最为合适的。下面单独把这部分定义剔出来讨论,代码如下。

union {

__IO uint32_t MASKED_ACCESS[4096];/*!< Offset: 0x0000 to 0x3FFC Port data Register for pins PIOn_0 to PIOn_11 (R/W) */

struct {

uint32_t RESERVED0[4095];

__IO uint32_t DATA;/*!< Offset: 0x3FFC Port data Register (R/W) */

};

};

可以看出,在共用体中定义了两个部分的复用内容。第一个部分是一个“uint32_t”型的MASKED_ACCESS(屏蔽)数组,一共定义了4096个元素空间。每个数组元素占用4个字节地址,4096个MASKED_ACCESS数组共占用0x3FFC的地址空间,每个单元都具有可读可写的属

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top