一、目的
在正点原子精英版上实现按键KEY0控制LED0状态的翻转,KEY1控制LED1状态的翻转,WK_UP同时控制LED0和LED1状态的翻转。
二、硬件电路分析
如下图所示,按键KEY0和KEY1一端连接在单片机PE4、PE3上,另外一端接地;按键WK_UP一端连接在单片机PA0上,另一端连接在3.3V电源上。所以在进行程序编写时,应将PE4、PE3引脚模式设置为上拉,将PA0引脚模式设置为下拉。
三、程序设计
1.按键端口初始化
(1)端口时钟初始化。
(2)端口模式配置。
void key_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//端口时钟初始化 KEY0-PE4,KEY1-PE3,WK_UP-PA0
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);
//端口模式配置 KEY0、KEY1上拉模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE,&GPIO_InitStructure);
//WK_UP下拉模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
2.按键扫描
u8 key_scanf(u8 mode) //mode为0不支持连续按,mode为1支持连续按
{
static u8 key_up = 1;
if(mode)
key_up = 1; //支持连续按
if(key_up && (KEY0 == 0||KEY1 == 0||WK_UP == 1))
{
delay_ms(10);
key_up = 0; //将标志位清0
if(KEY0 == 0)
return 1;
if(KEY1 == 0)
return 2;
if(WK_UP == 1)
return 3;
}
else if((KEY0 == 1)&&(KEY1 == 1)&&(WK_UP == 0))
key_up = 1;
return 0;
}
3.主函数
int main(void)
{
u8 key;
key_init();
delay_init();
LED_init();
while(1)
{
key = key_scanf(1);
if(key)
{
switch(key)
{
case 1 : //初始状态熄灭
LED0 = !LED0;
break;
case 2 : //初始状态熄灭
LED1 = !LED1;
break;
case 3 : //初始状态熄灭
LED0 = !LED0;
LED1 = !LED1;
break;
}
}
else
delay_ms(10);
}
}
注:
#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)
#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)