#define key1 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)
#define key2 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)
#define key3 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)
#define key4 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)
struct keys
{
uint8_t key_judge; // 状态位
_Bool key_sta;
uint8_t single_flg; //统计次数
_Bool longle_flg; //长按标志
uint8_t key_time; //按键状态
_Bool double_flg; //双击标志
_Bool one_flag; //单击标志
};
HAL_TIM_Base_Start_IT(&htim2); //开启定时器中断,进入回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //回调函数
{
if(htim->Instance == TIM2) //锁入TIM2
{
key[0].key_sta = key1; //接收状态
key[1].key_sta = key2;
key[2].key_sta = key3;
key[3].key_sta = key4;
for(uint8_t i = 0;i < 4; i++) //判断按键是哪一个按下
{
switch(key[i].key_judge)
{
case 0: if(key[i].key_sta == 0) //按下 case 0 退出后经过TIM 10ms消抖由key_judge = 1;再次进入case 1:
{
key[i].key_time = 0;
key[i].key_judge = 1;
}
break;
case 1: if(key[i].key_sta == 0) //同样进入case3
{
key[i].key_judge = 2;
}
else key[i].key_judge = 0;
break;
case 2:
if(key[i].key_sta == 1) //松手检测 //松手检测
{
if(key[i].key_time > 20 && key[i].key_time <= 70 ) //单击功能
{
key[i].one_flag = 1;
key[i].key_judge = 0;
}
if(key[i].key_time <= 20 ) //双击功能
{
key[i].single_flg++;
key[i].key_judge = 0;
if(key[i].single_flg == 2 ) //长按键功能
{
key[i].double_flg=1;
key[i].key_judge = 0;
key[i].single_flg =0;
}
}
else
{
key[i].longle_flg = 1;
key[i].key_judge = 0;
}
}
else
{
key[i].key_time++;
}
break;
}
}
}
}
1.按键三种模式同时实现,这个单击跟双击在一起是很矛盾的所以使用定时不同隔开,
2.由于开启定时器中断触发事件,每一次10ms进入函数,为什么是10ms由定时器重装载值和计数器决定。
3.重装载值和计数值在CUBE软件配置,此次实验开启中断2,配置重装载为10000,计数值为80,RCC那边配置的是80M,FC = 80M/80/10000 = 100;T = 倒数1/100 = 0.01s = 10ms