程序设计500ms一下为单击按键 500ms以上为连续按键 实验开发板为正点原子mini板,设计思想是,当按键按下是启动定时器计数,抬起按键定时器停止计数,如果在设定的500ms以内提起按键则视为单击一次,如果定时器计数时间超过500ms则视为长按。
- 设置按键引脚
#define KEY0 HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_5) //KEY0按键PC5
#define KEY1 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_15) //KEY1按键PA15
#define WK_UP HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) //WKUP按键PA0
#define KEY0_PRES 1
#define KEY1_PRES 2
#define WKUP_PRES 3
//按键初始化函数
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
__HAL_RCC_GPIOC_CLK_ENABLE(); //开启GPIOC时钟
GPIO_Initure.Pin=GPIO_PIN_0; //PA0
GPIO_Initure.Mode=GPIO_MODE_INPUT; //输入
GPIO_Initure.Pull=GPIO_PULLDOWN; //下拉
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_15; //PA15
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_5; //PC5
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
HAL_GPIO_Init(GPIOC,&GPIO_Initure);
}
- 开启一个定时器(timer3) 定时器定时时间为1ms。
HAL_TIM_Base_Start_IT(&htim3); // 开启定时器
- 按键扫描程序
// 按键按下触发条件
void Set_Press_Flag(void)
{
timer3_start_flag = 1;
key_press_flag = 1;
}
// 自动支持点击和长按按键 单击抬起生效
uint8_t KEY_Scan(void)
{
static uint8_t key_num = 200;
if(key_press_flag == 0)
{
if(KEY0==0||KEY1==0||WK_UP==1) // 有按键触发
{
HAL_Delay(10);
if(KEY0 == 0) // KEY0被按下
{
key_num = 0;
Set_Press_Flag();
}
else if(KEY1 == 0) // KEY1被按下
{
key_num = 1;
Set_Press_Flag();
}
else if(WK_UP == 1) // WK_UP被按下
{
key_num = 2;
Set_Press_Flag();
}
else
{
key_num = 200;
}
return 0;
}
else
{
return 0;
}
}
else
{
if(KEY0==1&&KEY1==1&&WK_UP==0)
{
key_press_flag = 0;
switch(key_num)
{
case 0:
timer3_start_flag = 0;
return KEY0_PRES;
case 1:
timer3_start_flag = 0;
return KEY1_PRES;
case 2:
timer3_start_flag = 0;
return WKUP_PRES;
}
}
}
return 0;
}
- 定时器处理函数
uint8_t timer3_start_flag = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim == &htim3)
{
if(timer3_start_flag)
{
timer3_count ++;
if(timer3_count > 500)
{
timer3_count = 2000;
HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET);
}
}
else
{
timer3_count = 0;
}
}
}
- 测试程序
void User_Sys_Init(void)
{
HAL_TIM_Base_Start_IT(&htim2);
HAL_TIM_Base_Start_IT(&htim3);
KEY_Init();
}
void Key_Handle()
{
static uint8_t key = 0;
key = KEY_Scan();
switch(key)
{
case KEY0_PRES:
printf("KEY0_PRES\r\n");
HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);
break;
case KEY1_PRES:
printf("KEY1_PRES\r\n");
HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);
break;
case WKUP_PRES:
printf("WKUP_PRES\r\n");
HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);
break;
}
}
int main()
{
User_Sys_Init();
while(1)
{
Key_Handle();
}
}