按键由于机械特性原因会产生抖动干扰程序的判断,所有要进行消抖,方法有多种,如:消抖电路,软件阻塞式延时消抖,定时器消抖等。
阻塞消抖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #define KEY = P1^1; #define LED = P1^2;
while(1) { if(KEY == 0) { delay_ms(10); if(KEY == 0) { LED = !LED; while(!KEY); } } }
|
GD32 滴答定时器按键消抖例子
首先说下 IO 口的配置,配置IO口为外部中断下降沿触发模式。
消抖过程
GD32 有一下几种外部中断触发模式:
1 2 3 4 5 6 7 8
| typedef enum { EXTI_TRIG_RISING = 0, EXTI_TRIG_FALLING, EXTI_TRIG_BOTH, EXTI_TRIG_NONE }exti_trig_type_enum;
|
GPIO 模式设置:
1
| gpio_mode_set(ENCODER_SW_GPIO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, ENCODER_SW_PIN);
|
使能 Nvic :
1
| nvic_irq_enable(ENCODER_SW_EXTI_IRQn, 1U, 1U);
|
外部中断线配置:
1
| syscfg_exti_line_config(ENCODER_SW_EXTI_PORT_SOURCE, ENCODER_SW_EXTI_PIN_SOURCE);
|
外部中断初始化
1
| exti_init(ENCODER_SW_EXTI_LINE, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
void encoder_handle(void) { FlagStatus SW_State = gpio_input_bit_get(ENCODER_SW_GPIO_PORT, ENCODER_SW_PIN); if(ec11_1.sw_down_flag == 1 && ec11_1.sw_down_time > 10) { if(SW_State == RESET) { test_number++; ec11_1.sw_down_flag = 0; ec11_1.sw_down_time = 0; } } }
|
中断回调函数
1 2 3 4 5 6 7 8 9 10 11
|
void EXTI2_3_IRQHandler(void) { if(SET == exti_interrupt_flag_get(ENCODER_SW_EXTI_LINE)){ ec11_1.sw_down_flag = 1; exti_interrupt_flag_clear(ENCODER_SW_EXTI_LINE); } }
|
滴答定时器回调
1 2 3 4 5 6 7 8 9
| void SysTick_Handler(void) { led_spark(); delay_decrement(); if(ec11_1.sw_down_flag == 1){ ec11_1.sw_down_time++; } }
|
滴答定时器回调实例2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void SysTick_Handler(void) { led_spark(); delay_decrement(); if(ec11_1.sw_down_flag == 1){ ec11_1.sw_down_time++; }
if(ec11_1.sw_mode_flag == 2) { ec11_1.sw_long_press_time++; } }
|
单击&双击&长按的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
void encoder_handle(void) { FlagStatus SW_State = gpio_input_bit_get(ENCODER_SW_GPIO_PORT, ENCODER_SW_PIN); if(ec11_1.sw_down_flag == 1 && ec11_1.sw_down_time > 10 && ec11_1.sw_down_count == 0) { if(SW_State == RESET) { ec11_1.sw_down_count = 1; } }
if(ec11_1.sw_down_count == 1 && ec11_1.sw_down_time > 500 && SW_State == RESET) { ec11_1.sw_mode_flag = 2; } if(ec11_1.sw_down_count == 1 && ec11_1.sw_down_time > 500 && SW_State == SET) { ec11_1.sw_down_count = 0; ec11_1.sw_down_time = 0; ec11_1.sw_down_flag = 0; ec11_1.sw_mode_flag = 0; }
if(ec11_1.sw_down_count == 1 && SW_State == SET && ec11_1.sw_down_time < 500) { ec11_1.sw_down_count = 2; ec11_1.sw_down_time = 0; }
if(ec11_1.sw_down_flag == 1 && ec11_1.sw_down_count == 2 && ec11_1.sw_down_time > 100) { if(SW_State == RESET) { ec11_1.sw_mode_flag = 3; ec11_1.sw_down_time = 0; ec11_1.sw_down_flag = 0; ec11_1.sw_down_count = 0; } else { ec11_1.sw_mode_flag = 1; ec11_1.sw_down_time = 0; ec11_1.sw_down_flag = 0; ec11_1.sw_down_count = 0; } }
if(ec11_1.sw_mode_flag == 2) { if(ec11_1.sw_long_press_time == LED_AUTO_SETP) { test_number++; ec11_1.sw_long_press_time = 0; } FlagStatus sw_state_temp = gpio_input_bit_get(ENCODER_SW_GPIO_PORT, ENCODER_SW_PIN); if(sw_state_temp == SET) { ec11_1.sw_mode_flag = 0; } } if(ec11_1.sw_mode_flag == 1) { test_number++; ec11_1.sw_mode_flag = 0; }
if(ec11_1.sw_mode_flag == 3) { test_number += 10; ec11_1.sw_mode_flag = 0; } }
inline void ec11_init(EC11_t ec11) { ec11.sw_down_time = 0; ec11.sw_mode_flag = 0; ec11.sw_down_flag = 0; ec11.sw_down_count = 0; ec11.sw_long_press_time = 0; }
|