最近在准备蓝桥杯嵌入式比赛,关注到按键的按压事件。
使用定时器来监听按压事件,并根据按压事件做出不同的变化
话不多说直接上代码:
#ifndef __FUNC_H__
#define __FUNC_H__
#include "main.h"
#include "tim.h"
#include "gpio.h"
#include "stdio.h"
#include "lcd.h"
struct key
{
unsigned char key_status;
unsigned char single_status;
unsigned char judge_status;
unsigned char long_status;
unsigned char double_status;
unsigned char num;
};
void lcd_proc(void);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
#endif
#include "func.h"
struct key keys[4];
unsigned char B1,B2;
uint16_t Tick,uctime;
void lcd_proc(void)
{
char text[20];
if (keys[0].single_status == 1)
{
LCD_ClearLine(Line1);
sprintf(text," K1:single ");
LCD_DisplayStringLine(Line1,(unsigned char *)text);
keys[0].single_status = 0;
}
else if (keys[0].long_status == 1)
{
LCD_ClearLine(Line1);
sprintf(text," K1:long ");
LCD_DisplayStringLine(Line1,(unsigned char *)text);
keys[0].long_status = 0;
}
else if (keys[0].double_status == 1)
{
LCD_ClearLine(Line1);
sprintf(text," K1:double ");
LCD_DisplayStringLine(Line1,(unsigned char *)text);
keys[0].double_status = 0;
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM3)
{
if (B1 == 1)
{
++Tick;
}
if (B2 == 1)
{
++uctime;
}
keys[0].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
keys[1].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
keys[2].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
keys[3].key_status = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
for(int i = 0; i < 4; i++)
{
switch(keys[i].judge_status)
{
case 0:
{
if (keys[i].key_status == 0) keys[i].judge_status = 1;
}
break;
case 1:
{
if (keys[i].key_status == 0)
{
keys[i].judge_status = 2;
keys[i].single_status = 1;
keys[i].num++;
}
else
keys[i].judge_status = 0;
}
break;
case 2:
{
if (keys[i].key_status == 1) keys[i].judge_status = 0;
}
break;
}
}
// 按下逻辑
if (keys[0].single_status == 1 && B1 == 0)
{
keys[0].single_status = 0;
B1 = 1;
B2 = 1;
}
// 过滤掉所有的按键
if (B1 == 1)
{
keys[0].single_status = 0;
}
// 500ms 自动判断点击次数
if (Tick >= 50)
{
B1 = 0;
Tick = 0;
if (keys[0].key_status == 1){
if(keys[0].num == 2)
keys[0].double_status = 1;
else if(keys[0].num == 1)
keys[0].single_status = 1;
keys[0].num = 0;
}
}
// 松手检测触发判断按压时间
if (keys[0].key_status == 1 && B2 == 1 && Tick == 0)
{
B2 = 0;
if (uctime > 100)
keys[0].long_status = 1;
else
keys[0].single_status = 1;
uctime = 0;
keys[0].num = 0;
}
}
}