Get the key press time value based on the length of time the key is pressed

This case uses the basic timer of the chip and uses the system clock of 16MHZ divided by 16. The obtained frequency is 1MHZ, the automatic reload value is 200, and each count period is 0.2ms.

1. Get the key time value and execute the function

unsigned char get_key_press_time(void)
{
    static u2 u2_key_scan_time=0; //The key value is the polling acquisition time
    static u1 u1_key_pin_value = 0; //Get the pin signal value of the key link (0/1)
    static u2 u2_key_press_continu_time=0; //The time the key is pressed continuously
    unsigned char u1_return_key_press_time = 0; // Required key return time
    static u1 u1_key_press_state=KEY_STATE_RELEASE; //Key state - (raise, press, shake, short press, 3s, 5s...)
    
    //1. Poll and query once every 3ms, and obtain the signal value of the button pin (0 or 1)
    u2Clock_1msInc( & amp;u2_key_scan_time); //1ms accumulates once, key scan time
    if(u2_key_scan_time >= 3) //Scan once every 3ms
    {
     u2_key_scan_time = 0; //Clear key scan time to 0
         u1_key_pin_value = ((GPIOA->DIN) & amp; 0x0002); //Get the value (signal) of the PA1 pin input register - the key value of the (SWI) pin
     }
    
    u2Clock_1msInc( & amp;u2_key_press_continu_time); //Start recording the time when the key is pressed
    
 
 
    //3. Determine the button status and return the button time according to different button status.
    switch(u1_key_press_state) //Determine the key state based on the key value
    {
        //If the button state is lifted
        case KEY_STATE_RELEASE:
          if(!u1_key_pin_value)
          {
             u2_key_press_continu_time = 0; //The key is pressed and the holding time is cleared to 0
             u1_key_press_state=KEY_STATE_RELEASE; //The key state is lifted
          }
         else
         {
            u1_key_press_state=KEY_STATE_PRESSDOWN; //The key state is pressed
          }
          
        break;
              
        //If the button is just pressed
        case KEY_STATE_PRESSDOWN: //If it is low level 0, it means the button is pressed
          //if lifted
          if(!u1_key_pin_value) //Read the value from the key control pin input data register
            {
               u2_key_press_continu_time = 0; //The key is pressed and the holding time is cleared to 0
               u1_key_press_state =KEY_STATE_RELEASE;
            }
            //If the button is kept pressed
            else //If no value is read from the key control pin
            {
              u2_key_press_continu_time = 0; //Clear 0 first to prepare for 20ms debounce
          u1_key_press_state = KEY_STATE_SHAKE; //The key state is the press shake state
      
            }
    break;
        
        //The first 20ms belong to the jitter elimination stage
    case KEY_STATE_SHAKE: //Key debounce, debounce time 20ms
          //If the button was lifted before 20ms
          if(!u1_key_pin_value) //If the value is read from the key control pin input data register
            {
                
                  u1_key_press_state = KEY_STATE_RELEASE; //The key press state is lifted RELEASE
                
            }
          //If it is kept pressed, the time passes 20ms and the short press stage is reached.
          
          else //If no value is read from the key control pin input data register
            { //Press to debounce
                if(u2_key_press_continu_time > 20) //1ms accumulates once to record the length of time the key is pressed.
                {
                   u1_key_press_state = KEY_STATE_SHORT; //The key state is short press state
                 }
            }
    break;
         
        //If the button press time enters the short press stage
    case KEY_STATE_SHORT: //If the button is pressed, the state is short press
            if(!u1_key_pin_value) //If it is pressed now
            {
                u2_key_press_continu_time = 0; //The key is pressed and the holding time is cleared to 0
        u1_key_press_state = KEY_STATE_RELEASE; //The key is pressed and the state is pressed
                u1_return_key_press_time = KEY_VALUE_SHORT;
            }
            else //if it is lifted
            {
              if(u2_key_press_continu_time >= 3000) //The observation time has reached 3s
              {
                u1_key_press_state = KEY_STATE_3S; //The key is pressed and held for 3s.
                u1_return_key_press_time = KEY_VALUE_3S; //Return 3s key value
              }
            }
    break;
        
        //If the button enters the press and hold stage for 3s
    case KEY_STATE_3S:
          if(!u1_key_pin_value)
          {
                u2_key_press_continu_time = 0; //The key is pressed and the holding time is cleared to 0
        u1_key_press_state = KEY_STATE_RELEASE; //The key press state is pressed
                u1_return_key_press_time = KEY_VALUE_3S; //Return 5s key value
                           
          }
          else
          {
            if(u2_key_press_continu_time >= 5000)
            {
                u1_key_press_state = KEY_STATE_5S; //The key state is pressed and held for 5s
                u1_return_key_press_time = KEY_VALUE_5S; //Return 5s key value
            }
          }
    break;
    
        //If the button enters the press and hold stage for 5s
    case KEY_STATE_5S:
          
          //If the button is released
          if(!u1_key_pin_value)
          {
                u2_key_press_continu_time = 0; //The key is pressed and the holding time is cleared to 0 //The key press status is pressed (the key here is pressed until 5s. If the value is assigned according to 5s, it cannot be selected)
                u1_key_press_state = KEY_STATE_RELEASE;
              
                u1_return_key_press_time = KEY_STATE_5S; //Return 5s key value
          }
          else
          {
            if(u2_key_press_continu_time >= 8000)
            {
                u1_key_press_state = KEY_STATE_8S; //The key state is pressed and held for 8s
                u1_return_key_press_time =KEY_STATE_8S; //Return 8s key value
            }
          }
        break;
                                                  
    default:
        u2_key_press_continu_time = 0; //The key is pressed and the holding time is cleared to 0
        u1_key_press_state= KEY_STATE_RELEASE; //The key press state is lifted
           
    break;
    }

    return u1_return_key_press_time; //Finally return key press hold time (short, 3, 5, 8)
    
}

2. Basic timer

//Basic timer handler
void BSTIM_IRQHandler(void)
{

//The basic timer here uses the system clock divided by 16 and 16MHZ. The obtained frequency is 1MHZ, the automatic reload value is 200, and each count period is 0.2ms.
    BSTIM32->ISR |= 0x1; //Clear the interrupt flag register (hardware set, software writes 1 to clear)
    tm_200us + + ; //Time 200 microsecond variable starts to accumulate
    tm_1ms + + ; //In order to obtain 1 millisecond basic timer count variable starts to accumulate
    if (tm_1ms == 5) //0.2ms*5=1ms
    {
        tm_1ms = 0; //Clear the variable to get 1 millisecond count to 0
        flag_1ms = 1; //1ms passed successfully
    }
    if (tm_200us == 100) //0.2ms*100=20ms
    {
        tm_200us = 0; //Clear the variable to get 20 milliseconds to 0
        flag_20ms = 1; //20ms passed successfully
    }

    if (0 == tm_1ms) //If the basic timer does not start counting
    {
        Time1ms_count + + ; //Start backup 1ms count accumulation
    }
    
    if (( 0 == ADCComplete) & amp; & amp;(Time1ms_count > 200)) //Time has passed 40ms and ADC conversion is not completed
    {
            FL_ADC_EnableSWConversion(ADC); //Enable ADC software to trigger conversion
            Time1ms_count = 0; //The backup 1ms count accumulation variable is cleared to 0
    }
    
    // FL_ADC_EnableSWConversion(ADC); //Enable ADC software to trigger conversion
}

3. Clock control flag

void clock_control(void)
{
    flag_20msseed = 0; //Last 20ms millisecond identification
    flag_1secseed = 0; //Identification of the past 1sec seconds
    flag_minseed = 0; //The past 1min minute mark
    flag_1msseed = 0; //Last 1ms millisecond identification
    
    if (flag_1ms) //reach 1 millisecond
    {
        flag_1ms = 0; //1ms variable is cleared to 0
        flag_1msseed = 1; //1 millisecond passed successfully
    }


    if (flag_20ms) //reach 20 milliseconds
    {
        flag_20ms = 0; //Clear the 20 millisecond flag
        flag_20msseed = 1; //The successful arrival of 20 milliseconds is marked as 1
        tm_20ms + + ;
        if (tm_20ms >= 50) //20*50=1000ms=1s
        {
            tm_20ms = 0; //20ms variable is cleared to 0
            flag_1secseed = 1; //1 second passed successfully
        }
    }


    if (flag_1secseed) //1 second
    {
        tm_1sec + + ;
        if (tm_1sec >= 60) //1s*60=60s=1min
        {
            tm_1sec = 0; //1s variable is cleared to 0
            flag_minseed = 1; //1 minute passed successfully
        }
    }
    
    flag_successed_copy = flag_1secseed; //Copy once every minute and return 1 successfully
}

4. 1ms timer

//1ms accumulates once
void u2Clock_1msInc(u2 *v)
{
    if (flag_1msseed) //The basic timer time has passed 1ms
    {
        if (*v < 0xffff) //Accumulate to ffff
        {
            (*v) + + ;
        }
    }
}

5. 1s timer

//1s accumulates once
void u2Clock_SecInc(u2 *v)
{
    if (flag_1secseed) //If time passes 1s
    {
        if (*v < 0xffff) //Accumulate to ffff
        {
            (*v) + + ;
        }
    }
}

6. 1min timer

//Accumulate once every 1 minute
void u2Clock_MinInc(u2 *v)
{
    if (flag_minseed) //Basic timer successfully passes 1 minute
    {
        if (*v < 0xffff) //Accumulate to ffff
        {
            (*v) + + ;
        }
    }
}