background
Some items use independent key detection, short press, long press. According to the use effect, it is found that it is easier to operate after the button is released, that is, after the button is popped up.
I remember that the blogger wrote an article about button detection before, but it was too complicated. It may be difficult to understand, but here is a little simpler, only one button is processed. And this button only detects two states of short press and long press.
hardware
The hardware schematic diagram is as follows
No matter which type of MCU is used here, it is basically the same, that is, the button is pulled up, and the MCU pin has a low-level input signal when the button is pressed. As shown in the picture below, I am allowed to be lazy here and bring up the previous picture. Because the picture of the actual project, it is not good to take it up. Anyway, the principle is like this, you can also pull up the KEY, and the pull-up here can be configured as an input pull-up on the pin of the MCU.
Press the button as shown in the figure below, and the MCU pin KEY gets a low level input.
software
This is not limited to the MCU used, and the button is scanned to obtain the button value.
First use the timer to time 1ms
This code is based on the MCU platform used to implement the initialization configuration of the timer to ensure that the timer is interrupted once every 1ms. The code here is different for different MCU platforms. For example, other 8-bit MCUs such as STM32/GD32/etc.
void timer_init(void)
{
//根据MCU平台实现,初始化代码
}
Timer interrupt function to realize key scanning
For key_val/key_val_buf here, you can understand the global variables, read the key message, and save the key value if there is a key.
void TIM_IRQHandler()
{
key_val = ReadKey();
if(key_val != NO_KEY)
{
key_val_buf = key_val;
}
}
Specifically detect the function of long press, here is the most critical
implemented with a state machine
code show as below
Here is a brief explanation, every time the timer is interrupted, first read the current value of the pin of the button
If the state is 0, it detects that a button is pressed, enters state 1, and eliminates the jitter
State 1 confirms that a button is pressed, then enters state 2
State 2 waits for the button to be released, and determines whether to output a long press or a short press according to the value of KeyTimeCnt
Here 2ms to 1000ms is a short press and
above 1000ms is considered a short press
This value can be adjusted according to your own usage habits. I also adjusted it according to the effect of the actual button.
unsigned char ReadKey(void)
{
static unsigned char KeyState = 0;
static unsigned int KeyTimeCnt = 0;
static unsigned int no_key_times = 0;
unsigned char KeyReturn = NO_KEY;
static unsigned char KeyCurValue = NO_KEY;
KeyCurValue = key; //读取按键值
switch(KeyState)
{
case 0:
{
if(KeyCurValue == 0) //检测到有键按下
{
KeyState++; //转到消抖确认状态
KeyTimeCnt = 0;
no_key_times = 0;
}
else
{
no_key_times++;
if(no_key_times >= 500)//500*20ms=10s
{
no_key_times = 0;
}
}
break;
}
case 1:
{
if(KeyCurValue == 0) //和上次按键相同确认有键按下
{
KeyState++; //转入等待按键释放状态
}
else
KeyState--; //两次键值不同 返回等待按键状态
KeyTimeCnt = 0;
break;
}
//增加时间按键的长按、短按检测
case 2:
{
if(NO_KEY == KeyCurValue) // 按键已经释放
{
if((KeyTimeCnt > 2) && (KeyTimeCnt < 1000))
{
KeyReturn = KEY1_DOWN;
KeyTimeCnt = 0;
KeyState = 0;
}
else if(KeyTimeCnt >= 1000)
{
KeyReturn = KEY1_DOWN_LONG; //检测到长按
KeyTimeCnt = 0;
KeyState = 0;
}
else
{
KeyReturn = NO_KEY;
KeyTimeCnt = 0;
KeyState = 0;
}
}
else
{
KeyTimeCnt++;
}
break;
}
default:
{
KeyState = 0;
break;
}
}
return KeyReturn;
}
The previous blog can also be referred to, it is a bit complicated
This button detection is much more complicated.