判断按键长按还是短按,就需要引入时间的概念了。
对于STM32G431RBT6这块板子来说,直接开启一个定时器用来检测即可。
?这里要讲到一个定时器时间计算公式
TLCK指的就是系统时钟频率,设置为100MHz的话,用公式计算,定时器6就是10ms产生一次定时中断。
?生成工程文件后,编程代码如下:
这样就可以每10ms检测一次按键
unsigned int count = 0,flag = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //定时中断回调函数
{
if(htim -> Instance == TIM6)
{
if( HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0) ==0 ) //读取B1的状态,按下为0
{
count++; //按键按下时,每10ms count就+1
}else if(count > 80) //如果按键按下大于800ms,就判断是长按
{
x = 1; //标志变量x = 1 长按
}
else if(count > 10 &&count <80) //如果按下时长不足 800ms 就判断是短按
x = 2;
}
}
当然使用定时器还要在主函数中启动它,用这句
HAL_TIM_Base_Start_IT(&htim6);
上面就是判断长按短按的方法。
还有一种就是,按下按键不松手的时候,系统会一直去执行按下的操作,但是当我们需要计数的时候,比如按下一次就令x++;这个时候按下一次,由于系统工作的速度是微秒级别的,会让x+上很多数,不能实现按一次就+1;
这个时候就要根据 按键按下前和按下后的两个状态来判断一次按下。
unsigned int flag = 0; //定义全局标志变量flag
void Key_scan()
{
static unsigned int x = 0; //定义静态变量 x 用于判断按键状态
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)== 0 && x == 0)
{
//如果按键按下,且前一瞬间没有按下,才算一次有效按下
x = 1; //x =1 表示前一次按键已经按下
flag = 1 ;
}else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)== 1)
x = 0; //如果不满足上面的状态,并且按键没有按下,x=0,表示前一瞬间没有按下
}
代码有一点点绕,仔细看的话逻辑起始挺简单的。
|