通过LED灯实验,学习LPC11C14的GPIO模块。
首先查看FS_11C14开发板的电路图,查看LED灯的连接方式
从电路图中可以看出,当LED1( LED2 )引脚给低电平时,LDE1( LED2 )灯导通
LED1、LED2两个引脚又分别连接了处理器的PIO3_0和 PIO3_1两个引脚
所以点亮LED1需要PIO3_0输出低电平,点亮LED2要PIO3_1输出低电平。
主程序如下
int main(void)
{
unsigned int i;
SystemInit();
GPIOInit();
// LED
GPIOSetDir(PORT3, 0, 1); // Set PIO3_0 to output
GPIOSetValue(PORT3, 0, 1); // PIO3_0 output 1, Turn off LED1
while(1) /* Loop forever */
{
for(i=0; i<250000; i++);
GPIOSetValue(PORT3, 0, 0);
for(i=0; i<250000; i++);
GPIOSetValue(PORT3, 0, 1);
}
}
出程序中主要是通过GPIOSetValue(PORT3, 0, 0)和GPIOSetValue(PORT3, 0, 1)分别控制PIO3_0和PIO3_1引脚的输出。
GPIOSetValue() 函数如下
/*****************************************************************************
** Function name: GPIOSetValue
**
** Descriptions: Set/clear a bitvalue in a specific bit position
** in GPIO portX(X is the port number.)
**
** parameters: port num, bit position, bit value
** Returned value: None
**
*****************************************************************************/
void GPIOSetValue( uint32_t portNum, uint32_t bitPosi, uint32_t bitVal )
{
LPC_GPIO[portNum]->MASKED_ACCESS[(1<<bitPosi)] = (bitVal<<bitPosi);
}
LPC_GPIO的定义:
static LPC_GPIO_TypeDef (* const LPC_GPIO[4]) = { LPC_GPIO0, LPC_GPIO1, LPC_GPIO2, LPC_GPIO3 };
可以看出LPC_GPIO[] 是一个指针数组,里面存放的内容为LPC_GPIO0, LPC_GPIO1, LPC_GPIO2, LPC_GPIO3。
在LPC11xx.h中定义
#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE )
#define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE )
#define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE )
#define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE )
可以很容易看出,LPC_GPIO0, LPC_GPIO1, LPC_GPIO2, LPC_GPIO3分别为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) */
&nbsnbsp; };
};
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) */
__IO uint32_t RIS; /*!< Offset: 0x8014 Raw interrupt status Register (R/ ) */
__IO uint32_t MIS; /*!< Offset: 0x8018 Masked interrupt status Register (R/ ) */
__IO uint32_t IC; /*!< Offset: 0x801C Interrupt clear Register (R/W) */
} LPC_GPIO_TypeDef;
/*@}*/ /* end of group LPC11xx_GPIO */
通过LPC_GPIO[portNum]->MASKED_ACCESS[(1<<bitPosi)] = (bitVal<<bitPosi);给相应地址内的寄存器写值
从而实现了对应端口的输出电平