STM32 independent keys realize the function of single click, double click and long press

Tip: after the article is written, the directory can be generated automatically. Please refer to the help document on the right for how to generate it

Article catalog

preface

When using STM32 or other MCU development projects, independent keys are often used for control.

Usually, an independent key needs to use one IO port. If the project needs to use keys to realize multiple functions, it often needs to use multiple keys and multiple IO ports. When the IO port resources are tight or you don't want to use too many keys. The following methods can be used to realize the functions of one key click, double click and long press to return different key values, so as to reduce the use of independent keys.

Tip: the following is the main content of this article. The following cases can be used for reference

1, Key function definition

Here, I regard pressing and holding the key for 3 seconds as a long press operation, and pressing it twice with an interval of 0.5s as a double click, otherwise it is a click

2, Use steps

1. Key initialization

The initialization part is the same as the normal independent key. You can refer to the code of punctual atom

The code is as follows (example):

The pull-up mode is used here

//Key initialization
void CtrlKey_Init(void) 
{ 
 	GPIO_InitTypeDef GPIO_InitStructure;
 
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//Enable clock

	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_12;//KEY0
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //Set to pull up
 	GPIO_Init(GPIOB, &GPIO_InitStructure);//Initialize IO port

}
 

2. Key scanning function (key)

In key Macro definition of key value in H

The code is as follows (example):

#define KEY0  GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) / / read the key

#define KEY0_PRES  	 one 	// single click
#define LONG_PRES 	 two 	// Long press
#define DOUBLE_PRES 	 three 	// double-click

In key C to write the scanning function, press the key to scan and return the corresponding key value

The code is as follows (example):

//In order to make the code less messy, I define a structure here. If you don't want to use the structure, you can directly define global variables
typedef struct {
  u32 u32time1;            //The timing starts after the first press. It is mainly used to judge the long press and add it in the timer
  u32 u32time2;            //Start timing after the first release. It is used to judge double clicking or clicking. It is added in the timer
  u8 u8key_flag;           //Press the sign for the first time
  u8 u8key_double_flag;    //Second sign
}Key_Tag;

Key_Tag skey;


u8 KEY_Scan()
{
    static u8 press = 0;
        
    if(KEY0==0)//Press the key
    {
        delay_ms(10);//Debounce
        if(KEY0==0)
        { 
            if(skey.u8key_flag==0)
            {
                skey.u8key_flag=1;        //The first press marks position 1. At the same time, the count value returns to zero
                skey.u32time1=0;
            }
            else if(skey.u8key_flag==1)
            {
                if(!press && skey.u32time1 > 3000)//If it is pressed for the first time and the time exceeds 3S, it is regarded as a long press
                {
                    press = 1;
                    return LONG_PRES;//Return long key value
                }
            }
        }
    }
    
    else if(KEY0==1)//Key release
    {
        if(skey.u8key_flag==1)    //The first key release
        {
            skey.u8key_flag=0;
            if(skey.u32time1>3000)//Press it for more than 3 seconds before releasing it. The key value has been returned. After releasing it, return the flag bits to zero
            {
                press = 0;
                skey.u32time1 = 0;
                skey.u32time2 = 0;
                skey.u8key_flag=0;
                skey.u8key_double_flag=0;
            }
            else if(skey.u8key_double_flag==0)
            {
                skey.u8key_double_flag=1;    //After the first release, mark position 1 begins to wait for the second key release
                skey.u32time2=0;            
            }
            else if(skey.u8key_double_flag==1)
            {
                if(skey.u32time2<500)            //If the second release interval is less than 0.5S, it is regarded as double clicking
                {
                    skey.u8key_double_flag=0;

                    return DOUBLE_PRES;
                }
            }
        }
        else if(skey.u8key_double_flag==1)
        {
            if(skey.u32time2>=500)            
            {
                skey.u8key_double_flag=0;

                return KEY0_PRES;//If there is no second key operation 0.5s after the first release, it is regarded as a short press
            }
        }
    }
    return 0;//No key pressed to return to 0
}

3. Precautions

time1 and time2 timing variables should be added in the timer. No detailed code will be released here.

Call the key scanning function by polling in the main function, obtain the key value, and then perform the corresponding operation according to the key value. It is the same as the key scanning function in peacetime

summary

This method is relatively simple. It is mainly to record the duration of the first press after the key is pressed. If it meets the long press standard, it will be regarded as long press. It is recommended that the long press time should not be less than 1 second. Record the second time after the first key release. If it is pressed and released for the second time within the specified interval, it is regarded as double clicking. If it is not pressed and released for the second time within the specified time, it is regarded as clicking.

Xiaobai has not been in the business for a long time. He may write a general blog for the first time. I hope you don't spray. If there are any mistakes, please correct them.

Keywords: Single-Chip Microcomputer stm32

Added by eugeniu on Tue, 11 Jan 2022 01:12:20 +0200