按键扫描原理
- 按键扫描即扫描IO口电平状态,来判断按键是否按下。当按键按下时,IO口电平发生改变。
- 由于按键在按下过程中,按键内部簧片接触过程中会出现很短暂的电平不稳定状态,一般需要去抖。方式有两种,第一种物理去抖,第二种软件去抖。本篇采用软件去抖,即5~10ms的延时。
扫描程序
- 在key.h中进行引脚宏定义
/* key0 define */
#define KEY0 PEin(4)
#define KEY0_GPIO_Pin GPIO_Pin_4
#define KEY0_GPIO_Port GPIOE
#define KEY0_RCC_APB2Periph_CLK RCC_APB2Periph_GPIOE
/* key1 define */
#define KEY1 PEin(3)
#define KEY1_GPIO_Pin GPIO_Pin_3
#define KEY1_GPIO_Port GPIOE
#define KEY1_RCC_APB2Periph_CLK RCC_APB2Periph_GPIOE
/* key_up define */
#define WK_UP PAin(0)
#define KEY_UP_GPIO_Pin GPIO_Pin_0
#define KEY_UP_GPIO_Port GPIOA
#define KEY_UP_RCC_APB2Periph_CLK RCC_APB2Periph_GPIOA
- 定义枚举值,用于扫描返回值
typedef enum _KEY_STA_t KEY_STA_t;
enum _KEY_STA_t
{
KEY0_PRESS = 1,
KEY1_PRESS,
WK_UP_PRESS
};
- 在key.c中进行按键的IO口定义
/**
* @name: KEY_GPIO_Init
* @description: KEY 初始化
* @param {*}
* @return {*}
*/
void KEY_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(KEY0_RCC_APB2Periph_CLK | KEY_UP_RCC_APB2Periph_CLK, ENABLE);
GPIO_InitStruct.GPIO_Pin = KEY0_GPIO_Pin;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(KEY0_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_Pin;
GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = KEY_UP_GPIO_Pin;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(KEY_UP_GPIO_Port, &GPIO_InitStruct);
}
- 按键扫描函数定义
/**
* @name: KEY_Scan
* @description: 按键扫描
* @param {u8} mode mode=0 表示开启连按; mode=1 表示不能连按;
* @return {*}
*/
u8 KEY_Scan(u8 mode)
{
static u8 key_up = 1;
if(mode) key_up = 1;
if(KEY0 == 1 && KEY1 == 1 && WK_UP == 0)
{
key_up = 1;
}
if(key_up && (KEY0 == 0 || KEY1 == 0 || WK_UP == 1))
{
delay_ms(10);
if(KEY0 == 0 || KEY1 == 0 || WK_UP == 1)
{
key_up = 0;
if(KEY0 == 0) return KEY0_PRESS;
if(KEY1 == 0) return KEY1_PRESS;
if(WK_UP == 1) return WK_UP_PRESS;
}
}
return 0;
}
按键扫描运行
- 在main.c中调用
int main(void)
{
uint8_t key_sta = 0;
uint32_t t = 0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
initSysTick();
Usart1_Init(115200);
LED1_Init();
LED2_Init();
KEY_GPIO_Init();
printf("Init Hardware OK ... \n");
for(;;)
{
t++;
if(t >= 2000)
t = 0;
/* 按键开关程序 */
key_sta = KEY_Scan(0);
if(key_sta == KEY0_PRESS)
{
LED1_Open();
printf("key0 press! \n");
}
if(key_sta == KEY1_PRESS)
{
LED1_Close();
printf("key1 press! \n");
}
/* 系统正常指示灯 */
if(0 == t % 100)
{
LED2_Toggle();
}
}
}
- 程序运行结果,串口中的显示
喜欢请点个赞哦,谢谢!欢迎指正