In the work I submitted, I used the polling method in the main loop to obtain the long and short key values. It is simple and practical and can meet the needs of the project. As many forum friends pointed out, the polling method cannot do other things when reading the length of the key, and the efficiency is too low. In some cases, it will also affect the MCU's processing of other affairs. Many forum friends suggested using the timer method, but at that time, in order not to affect the progress of the project submission, I used the polling method. During this period of free time, I optimized the key acquisition in the project code and used the timer to accumulate key values to identify the long and short keys. After testing, it fully achieved the expected purpose.
The basic idea of using the timer method is to set two global variables keys and keyf. The former counts and the latter marks the end of the key press. The timer is 10 milliseconds, and keys is an 8-bit variable with a maximum count of 255. It can distinguish key press times within 2.55 seconds (if it is greater than 2.55 seconds, it will be calculated as 2.55 seconds). Through experiments, the key value returned when the key is pressed and released quickly (clicked) is usually around 10, and the key value returned after pressing and releasing (short press) is about 30~40. The key value returned after pressing and waiting for a while before releasing (medium press) is about 60~90. The key value returned after pressing and counting twice and then releasing (long press) is about 120~180. The key value returned after pressing and counting four times and then releasing (super long press) will be greater than 200. In my project, the corresponding relationship between key values and functions is shown in the following table:
keys |
Classification |
mode>6 |
chick=1 |
mode=1~6 |
Alarm settings |
Query |
Calendar settings |
<20 |
Tap |
Slow increase |
Flip down |
Slow increase |
20~49 |
Short press |
Fast growth |
Flip up |
Fast growth |
50~99 |
Middle Press |
Rotation |
|
Rotation |
100~199 |
Long press |
|
advance and retreat |
|
>200 |
Super long press |
advance and retreat |
|
|
Below is the code for timer 2 configuration:
void timer_config(void)
{
/* -----------------------------------------------------------------------
TIMER2CLK is 100KHz定时器2 CLK为100kHz
TIMER2 channel0 duty cycle = (25000/ 50000)* 100 = 50%
----------------------------------------------------------------------- */
timer_oc_parameter_struct timer_ocintpara; //定义数据结构
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(RCU_TIMER2); //开启时钟
timer_deinit(TIMER2); //指定定时器
/* TIMER configuration 定时器配置*/
timer_initpara.prescaler = 719;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 999; //定时10毫秒
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER2,&timer_initpara);
/* configurate CH0 in PWM mode0 在PWM模式0中配置CH0*/
timer_interrupt_enable(TIMER2, TIMER_INT_UP); //Enable TIMER2
nvic_irq_enable(TIMER2_IRQn, 0); //Set priority to 0(0-2)
/* auto-reload preload enable 自动重新加载预加载启用*/
timer_auto_reload_shadow_enable(TIMER2);
/* auto-reload preload enable */
timer_enable(TIMER2);
}
In my project, Timer 2 not only counts the buttons but also serves as an alarm delay. For details, see the interrupt handling code below:
//The interrupt handler function of tmer2//
void TIMER2_IRQHandler(void)
{
if(RESET != timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_UP))
{
if(time>0) //在报警状态,延时减1(10毫秒)
time--;
if(keyf==0) //按键处理等待状态(keyf=1时,上次按键尚未处理完毕)
{
if(1==gd_eval_key_state_get(KEY_WAKEUP)) //按键按下
{
if(keys<255)
keys++; //按键计数
}
else
{
if(keys>0)
keyf = 1;//置按键松开标志
}
}
}
timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
}
The following is the code for detecting key presses in the main loop. When a key press event is detected, in addition to calling the key press processing function, the key press value is reset to zero and the key press event processing completion flag is set:
// 轮询按键处理
if(keyf > 0){ //有键按下
key_processing();
keys = 0;
keyf = 0; //置按键处理完毕标志
}
|