LPC1114通用输入/输出端口(GPIO)
在第一节中已经介绍过,LPC1114处理器是一个32位结构的处理器,但它的GPIO端口没有把32根引脚都接出来,而是每组只接出来12根引脚(注意,第四组只接出来6根引脚),共有4组,一共42根引脚。它们都具有如下特点:
1.可通过软件配置GPIO引脚为输入或输出
2.每个独立的端口引脚均可作为外部中断的输入引脚(边沿或电平触发)
3.边沿触发中断可配置为上升沿触发、下降沿触发以及双边沿触发
4.电平触发中断引脚可以配置为高电平或低电平触发
5.所有GPIO引脚默认情况下均为输入
6.从端口读取和写入数据操作可以通过地址位13:2屏蔽
端口的具体使用配置会在后面一一进行讨论,这里先来看一下“通用输入/输出端口GPIO”的结构体是如何定义的,代码如下。
typedef struct
{
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 RESERVED1[4096];
__IO uint32_t DIR;/*!< Offset: 0x8000 Data direction Register (R/W) */
__IO uint32_t IS;/*!< Offset: 0x8004 Interrupt sense Register (R/W) */
__IO uint32_t IBE;/*!< Offset: 0x8008 Interrupt both edges Register (R/W) */
__IO uint32_t IEV;/*!< Offset: 0x800C Interrupt event Register(R/W) */
__IO uint32_t IE;/*!< Offset: 0x8010 Interrupt mask Register (R/W) */
__I uint32_t RIS;/*!< Offset: 0x8014 Raw interrupt status Register (R/ ) */
__I uint32_t MIS;/*!< Offset: 0x8018 Masked interrupt status Register (R/ ) */
__O uint32_t IC;/*!< Offset: 0x801C Interrupt clear Register (R/W) */
} LPC_GPIO_TypeDef;
上述代码对LPC1114的GPIO端口的进行了结构体定义,由于GPIO位于内存地图中的AHB部分,所以从代码中可以看出,同前面讨论的结构体一样,它定义的成员变量利用偏移地址与AHB中的GPIO寄存器进行了对映。特殊的地方在于多了一个关于union的定义,要弄清这个定义,还必须回到AHB模块部分的寄存器描述中去。下图就给出了AHB模块内GPIO部分的寄存器分布情况。
对应上图与结构体中的内容可以看出,除了GPIODATA以外,其它寄存器与结构体成员的对映关系与前面讨论的SYSCON的一样。但对于GPIODATA就不能用前面的方法来分析了。下面就着重来讨论一下GPIODATA寄存器与其结构体成员之间是如何进行对映的。GPIODATA寄存器是GPIO的数据寄存器,它存放的数据直接被输出到GPIO的引脚上,引脚输入的数据也会被放到该寄存器中。所以要对端口进行电平控制(无论是输入还是输出),就要对GPIODATA寄存器进行操作。同样,GPIODATA寄存器也是一个32位的结构,其地址占用4个字节。而GPIO端口只有12个引脚,因此GPIODATA寄存器只用了低12位来对映GPIO端口引脚。
从上图中还可以看出,GPIODATA寄存器的偏移地址是从0x0000~0x3FFC。最高地址是0x3FFC是因为,每个GPIODATA寄存器单元占用4 字节,所以共有0x3FFC/4=0xFFF个(即4095个)GPIODATA寄存器单元,因为地址是从第0个单元算起的,所以总共有4096个单元。而2的12次方刚好就等4096,所以它刚好可以表征12个引脚的容量。由此可以看出,每个引脚电平的值(无论是输入还是输出)都可以在GPIODATA寄存器中找到一个对映的单元(因为有4096个引脚状态就有4096个GPIODATA地址单元)。这样做是为什么呢?为什么不把端口引脚统一用一个端口寄存器来描述(姑且称为“方法一”),写(或读)这个端口寄存器不就行了?其实,其它大部分单片机也确实是这样做的。而这里LPC1114却要花费4096个地址单元来把引脚状态全部描述一遍(姑且称为“方法二”),也肯定是有它的理由的。其实,应该说LPC1114是两种方法都包含的(因为严格来说,“方法一”包含于“方法二”)。至于“方法二”的优点,其实就是可以在不改变其它引脚状态下,单独改变某一引脚上的电平。按理说,通过“与或”的逻辑操作方式,也可以让“方法一”实现这一功能(其它单片机也是这样做的),但它必须通过“读——修改——写”的步骤来实现。比如要实现仅对P0端口的第7个引脚输出高电平,程序可写为“P0 |= 1
LPC1114输入输出端口GPI 相关文章:
- LPC1114通用输入/输出端口(GPIO)续(11-13)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)