赞
踩
本文使用cubemx软件,利用定时器10ms中断实现按键的长按、短按、双击。
定时器通常是通过一个晶体振荡器和一个计数器实现的。晶体振荡器可以产生稳定的时间基准,计数器可以根据振荡器提供的稳定时钟信号进行计数。当计数达到预设的值时,计数器就会触发一个中断信号。通过调整计数器的预设值和时钟信号的频率,我们就可以实现不同时间间隔的定时器。
例如,我们的频率为80MHz,我们可以将分频系数设置为80-1,重装载值设置为10000-1,则中断时间为80000000/80/10000=100HZ,1/100=0.01秒,即10ms。
定时器10ms进入一次中断,回调函数中读取引脚电平状态,由于按键抖动不会超过10ms,通过多次引脚电平保持时长进行判断,可实现短按、长按、双击。
时钟树配置:
定时器配置(蓝桥杯选手建议使用TIM6):
记得开启NVIC:
引脚配置为输入状态即可。
开启定时器中断代码如下:
HAL_TIM_Base_Start_IT(&htim6);
中断回调函数如下:
-
- struct keystruct {
- uint8_t keyLevel;
- uint8_t keyShort;
- uint8_t keyLong;
- uint8_t KeyDouble;
- uint8_t keyTime1;
- uint8_t keyTime2;
- uint8_t keyChoose;
- }key[4];
-
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- key[0].keyLevel=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
- key[1].keyLevel=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
- key[2].keyLevel=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
- key[3].keyLevel=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
- for(int i=0;i<4;i++)
- {
- switch(key[i].keyChoose)
- {
- case 0:
- if(key[i].keyLevel==0)
- key[i].keyChoose=1; //按下
- break;
- case 1:
- if(key[i].keyLevel==0)
- key[i].keyChoose=2; //消抖
- else
- key[i].keyChoose=0; //去抖
- break;
- case 2:
- if(key[i].keyLevel==0) //单击计时
- key[i].keyTime1++;
- else
- key[i].keyChoose=3; //已松手
- break;
- case 3:
- if(key[i].keyLevel==1)
- {
- key[i].keyTime2++; //等待双击开始计时
- if(key[i].keyTime2>30) // 等待时间过长,长按短按判断
- {
- if(key[i].keyTime1<70)
- key[i].keyShort=1; //是短按
- else
- key[i].keyLong=1; //长按
- key[i].keyChoose=0; //清除标志
- key[i].keyTime1=0;
- key[i].keyTime2=0;
- }
- }
- else
- key[i].keyChoose=4; //双击开始
- break;
- case 4:
- if(key[i].keyLevel==0) //不是消抖
- key[i].keyChoose=5;
- else //是抖动
- {
- if(key[i].keyTime1<70)
- key[i].keyShort=1; //是短按
- else
- key[i].keyLong=1; //长按
- key[i].keyChoose=0;
- key[i].keyTime1=0;
- key[i].keyTime2=0;
- }
- break;
- case 5:
- if(key[i].keyLevel==1) //双击松手
- {
- key[i].KeyDouble=1;
- key[i].keyChoose=0;
- key[i].keyTime1=0;
- key[i].keyTime2=0;
- }
- break;
- }
- }
- }
屏幕显示代码如下:
- void keyProc(void)
- {
- char chPorc[21];
- for(int i=0;i<4;i++)
- {
- if(key[i].keyShort==1)
- {
- key[i].keyShort=0;
- sprintf(chPorc,(const char *)"KEY SHORT = %d ",i+1);
- LCD_DisplayStringLine(Line2,(u8 *)chPorc);
- }
- if(key[i].keyLong==1)
- {
- key[i].keyLong=0;
- sprintf(chPorc,(const char *)"KEY LONG = %d ",i+1);
- LCD_DisplayStringLine(Line2,(u8 *)chPorc);
- }
- if(key[i].KeyDouble==1)
- {
- key[i].KeyDouble=0;
- sprintf(chPorc,(const char *)"KEY DOUBLE = %d ",i+1);
- LCD_DisplayStringLine(Line2,(u8 *)chPorc);
-
- }
-
- }
- }
mian函数中调用一下即可
链接:https://pan.baidu.com/s/1-tUgoAmMSVSJ0tivBjPNJQ?pwd=la74
提取码:la74
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。