STM32学习笔记之按键输入实验
借助正点原子F103战舰V3开发板进行学习,采用库函数编程。
参考资料:正点原子教学视频,《STM32F1开发指南-库函数版本_V3.3》
**硬件连接:**KEY0连接到PE4,KEY1连接到PE3,KEY2连接到PE2,另一端接地,KEY_UP连接到PA0,另一端接高电平。
所以PE2、PE3、PE4低电平时表示按键按下,PA0高电平时表示WK_UP按下。
与前两个实验不同,LED和蜂鸣器实验均是GPIO输出,按键实验是输入,需要用库函数GPIO_ReadInputDataBit()读取GPIO口电平。
在key.h中定义好读取到的电平标志,按键按下标志并创建一个按键初始化函数和按键扫描函数,完整代码如下:
/********** key.h **********/
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4) //电平标志
#define KEY1 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3)
#define KEY2 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2)
#define WK_UP GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)
#define KEY0_PRES 1 //KEY0按下
#define KEY1_PRES 2 //KEY1按下
#define KEY2_PRES 3 //KEY2按下
#define KEY_UP_PRES 4 //KEY_UP按下(即WK_UP/KEY_UP)
void KEY_Init(void); //按键初始化函数
u8 KEY_Scan(u8); //按键扫描函数
#endif
在key.c中写好前面定义好的按键初始化函数和按键扫描函数,GPIO初始化与LED实验和蜂鸣器实验有些不同,KEY0,KEY1,KEY2接地采用上拉输入,WK_UP接高电平采用下拉输入。按键初始化函数如下:
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //KEY0,KEY1,KEY2一端接的地,需上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_3 | GPIO_Pin_2; //初始化GPIOE2,3,4
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //KEY_UP一端接的高电平,需下拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //初始化GPIOA0
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
按键扫描有两种模式,一种是支持连按、一种不支持连按,设置一个输入参数mode,mode=1时表示支持连按,mode=0时表示不支持连按;同时需要延时去抖,定义一个按键松开标志key_up,key_up=1时表示按键松开,按键扫描函数如下:
u8 KEY_Scan(u8 mode)
{
static u8 key_up = 1; // 按键松开标志
if(mode)
key_up = 1;
if(key_up&&(KEY0==0 || KEY1==0 || KEY2==0 || WK_UP==1)) //按键按下
{
delay_ms(10); //延时去抖
key_up = 0; //按键按下
if(KEY0==0)
return KEY0_PRES;
else if(KEY1==0)
return KEY1_PRES;
else if(KEY2==0)
return KEY2_PRES;
else if(WK_UP==1)
return KEY_UP_PRES;
}
else if(KEY0==1 || KEY1==1 || KEY2==1 || WK_UP==0) //按键松开
key_up = 1;
return 0;
}
用KEY0控制LED0翻转,KEY1控制LED1翻转,KEY2控制LED0和LED1同时翻转,用WK_UP控制LED0和LED1同时亮起并使蜂鸣器响起,主函数代码如下:
int main(void)
{
vu8 key = 0;
LED_Init();
delay_init();
BEEP_Init();
KEY_Init();
while(1)
{
key = KEY_Scan(0); // 得到不支持连按的键值
if(key)
{
switch(key)
{
case KEY0_PRES:
LED0 = !LED0; //控制LED0翻转
break;
case KEY1_PRES:
LED1 = !LED1; //控制LED1翻转
break;
case KEY2_PRES:
LED0 = !LED0;
LED1 = !LED1; //控制LED0和LED1同时翻转
break;
case KEY_UP_PRES:
BEEP = !BEEP;
LED0 = 0;
LED1 = 0; //控制LED0和LED1亮起起蜂鸣器响起
}
}
else delay_ms(10);
}
}
编译无误后,用ST-Link将程序下载到开发板中,实验效果如预期。
上一篇: stm32 按键 扫描 实验
下一篇: STM32之按键输入实验