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) + + ; } } }