一、原理图
二、CubeMX配置
引脚PB0、PB1、PB2、PA0都配置为GPIO_Input,并设置为上拉输入Pull_up
设置定时器4,1ms,开中断
三、代码
1.短按
开启定时器中断
HAL_TIM_Base_Start_IT(&htim4);
button放主循环,每1ms扫描一次键值
void button()
{
switch(key)
{
case 1:
{
num++;
key=0;
}
break;
case 2:
{
num--;
key=0;
}
break;
case 3:
{
num=0;
key=0;
}
break;
case 4:
{
num=20;
key=0;
}
break;
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if( htim->Instance==TIM4 )
{
static unsigned char key_old=0;
unsigned char key_new,key_up,key_down;
key_new=key_scan();
key_down=key_new&(key_new^key_old);
key_up=~key_new&(key_new^key_old);
key_old=key_new;
if( key_up )
{
key=key_up;
}
}
}
unsigned char key_scan()
{
unsigned char key_result=0;//这句话一定不能忘记等于0
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET) key_result=1;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET) key_result=2;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==GPIO_PIN_RESET) key_result=3;
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET) key_result=4;
return key_result;
}
2.长按
开启定时器中断
HAL_TIM_Base_Start_IT(&htim4);
key和key_n均为全局变量
void key_pro()
{
switch(key)
{
case 1:
{
num++;
key=0;
}
break;
case 2:
{
num--;
key=0;
}
break;
case 3:
{
key=0;
}
break;
case 4:
{
key=0;
}
break;
}
switch(key_long)
{
case 1:
{
num++;
}
break;
case 2:
{
num--;
}
break;
case 3:
{
}
break;
case 4:
{
}
break;
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if( htim->Instance==TIM4 )
{
unsigned char key_new,key_down,key_up;
static unsigned char key_old=0;
key_new=key_scan();
key_down=key_new&(key_new^key_old);
key_up=~key_new&(key_new^key_old);
key_old=key_new;
if( key_down )
{
long_time=0;
long_time++;
}
if( key_up )
{
if( long_time<50 ) key=key_up;
}
if( long_time!=0 )
{
long_time++;
}
if( long_time>50 ) key_long=key_new;
}
}
3.双击
开启定时器中断
HAL_TIM_Base_Start_IT(&htim4);
设置double_time和double_key
在按键松开后计后,大于0.01s,键值不一样(key_double=1),算单击;
在按键松开后计后,大于0.01s,键值一样(key_double=2),算双击;
void key_pro()
{
switch(key_double)
{
case 1:
{
key=0;
key_double=0;
}
break;
case 2:
{
key=0;
key_double=0;
}
break;
case 3:
{
num[2]++;
key=0;
key_double=0;
}
break;
case 4:
{
num[2]--;
key=0;
key_double=0;
}
break;
}
if( time_double>20 )
{
switch(key)
{
case 1:
{
key=0;
}
break;
case 2:
{
key=0;
}
break;
case 3:
{
num[0]++;
key=0;
}
break;
case 4:
{
num[0]--;
key=0;
}
break;
}
}
switch(key_long)
{
case 1:
{
key_long=0;
}
break;
case 2:
{
key_long=0;
}
break;
case 3:
{
num[1]++;
key_long=0;
}
break;
case 4:
{
num[1]--;
key_long=0;
}
break;
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if( htim->Instance==TIM4 )
{
static unsigned char key_old=0;
unsigned char key_new,key_down,key_up;
key_new=key_scan();
key_down=key_new&(key_new^key_old);
key_up=~key_new&(key_new^key_old);
key_old=key_new;
if( key_up )
{
if( time_long<70&&double_1!=11 ) key=key_up;
long_1=0;
time_double=0;
time_double++;
if( double_1==11 ) double_1=0;
else double_1=key_up;
}
if( key_down )
{
time_long=0;
time_long++;
long_1=key_down;
if( double_1==key_down&&time_double<=20 )
{
double_1=11;
key_double=key_down;
}
}
if( time_long!=0 ) time_long++;
if( time_long>70 ) key_long=long_1;
if( time_double!=0 ) time_double++;
}
}