百度站长平台网页手机,wordpress入门书籍,推广链接,抄袭网站设计单片机长短按简单实现 目录 单片机长短按简单实现1 原理2 示例代码2.1 按键实现 3 测试log4 其他实现方式 1 原理
按键检测和处理的步骤如下#xff1a;
1#xff1a;定时扫描按键#xff08;使用定时器定时扫描#xff0c;也可以用软件延时或者系统心跳之类的方式#…单片机长短按简单实现 目录 单片机长短按简单实现1 原理2 示例代码2.1 按键实现 3 测试log4 其他实现方式 1 原理
按键检测和处理的步骤如下
1定时扫描按键使用定时器定时扫描也可以用软件延时或者系统心跳之类的方式总之能保证每次扫描间隔时间固定并且在一个较小的范围即可。 2扫描到有按键按下通常是检测GPIO的电平状态来判断按键是否按下具体情况需要结合实际硬件电路来看。 3开始计时记录按键持续按下的时间。 4若按下的时间达到了短按的时间具体多长的时间为短按由自己定义选择触发按键处理按下即触发或者先记录状态等按键释放时再触发按键处理弹起时触发。 5按键时间超过短按时间继续计时。 6按键时间达到长按时间具体多长的时间为长按由自己定义选择触发按键处理按下即触发或者先记录状态等按键释放时再触发按键处理弹起时触发。
2 示例代码
该示例使用的GD32共配置了4个按键特点如下
1按键按下时电平为0释放时为1。 2短按时间为30ms。 3长按时间为1s。 4短按释放时触发按键处理。 5长按按下时即触发按键处理。 6按键扫描和按键处理均放在定时器中断服务函数若按键处理的时间较长建议分开操作按键扫描还是放在中断按键处理放在其他地方以免长时间占用中断时间。 7按键处理我这里都是留空的只用串口打印了一句话表明已经触发了按键处理具体处理什么东西看实际需求。
注示例代码仅供参考还需要按具体需求修改。
2.1 按键实现
key.c
#include key.h
#include main.hkey_t key1;
key_t key2;
key_t key3;
key_t key4;void timer_user_init(void);// 按键初始化
void key_user_init(void)
{/* enable the key clock */rcu_periph_clock_enable(KEY1_CLOCK);rcu_periph_clock_enable(KEY2_CLOCK);rcu_periph_clock_enable(KEY3_CLOCK);rcu_periph_clock_enable(KEY4_CLOCK);/* configure key gpio port */ gpio_init(KEY1_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, KEY1_PIN);gpio_init(KEY2_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, KEY2_PIN);gpio_init(KEY3_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, KEY3_PIN);gpio_init(KEY4_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, KEY4_PIN);timer_user_init(); // 启动定时器定时扫描按键
}// 按键扫描
int key_scan(void)
{if(READ_KEY1_STATE KEY_PRESSED (key1.status 0)){if(key1.debounce KEY_SHORT_PRESSED){// 短按key1.status 1;// LOG(key1 short pressed.\n);}}else if(READ_KEY1_STATE KEY_PRESSED (key1.status 1)){if(key1.debounce KEY_LONG_PRESSED){// 长按key1.status 2;key1.debounce 0;// LOG(key1 long pressed.\n);return KEY1_LONG_PRESSED;}}else if((READ_KEY1_STATE KEY_RELEASED) (key1.status 0)){if(key1.status 1){// 短按释放key1.status 0;key1.debounce 0;return KEY1_SHORT_PRESSED;}if(key1.status 2){// 长按释放key1.status 0;key1.debounce 0;}}if(READ_KEY2_STATE KEY_PRESSED (key2.status 0)){if(key2.debounce KEY_SHORT_PRESSED){// 短按key2.status 1;}}else if(READ_KEY2_STATE KEY_PRESSED (key2.status 1)){if(key2.debounce KEY_LONG_PRESSED){// 长按key2.status 2;key2.debounce 0;return KEY2_LONG_PRESSED;}}else if((READ_KEY2_STATE KEY_RELEASED) (key2.status 0)){if(key2.status 1){// 短按释放key2.status 0;key2.debounce 0;return KEY2_SHORT_PRESSED;}if(key2.status 2){// 长按释放key2.status 0;key2.debounce 0;}}if(READ_KEY3_STATE KEY_PRESSED (key3.status 0)){if(key3.debounce KEY_SHORT_PRESSED){// 短按key3.status 1;}}else if(READ_KEY3_STATE KEY_PRESSED (key3.status 1)){if(key3.debounce KEY_LONG_PRESSED){// 长按key3.status 2;key3.debounce 0;return KEY3_LONG_PRESSED;}}else if((READ_KEY3_STATE KEY_RELEASED) (key3.status 0)){if(key3.status 1){// 短按释放key3.status 0;key3.debounce 0;return KEY3_SHORT_PRESSED;}if(key3.status 2){// 长按释放key3.status 0;key3.debounce 0;}}if(READ_KEY4_STATE KEY_PRESSED (key4.status 0)){if(key4.debounce KEY_SHORT_PRESSED){// 短按key4.status 1;}}else if(READ_KEY4_STATE KEY_PRESSED (key4.status 1)){if(key4.debounce KEY_LONG_PRESSED){// 长按key4.status 2;key4.debounce 0;return KEY4_LONG_PRESSED;}}else if((READ_KEY4_STATE KEY_RELEASED) (key4.status 0)){if(key4.status 1){// 短按释放key4.status 0;key4.debounce 0;return KEY4_SHORT_PRESSED;}if(key4.status 2){// 长按释放key4.status 0;key4.debounce 0;}}return -1;
}// 按键处理
void key_handle(void)
{static uint8_t key_state;uint8_t i;static uint8_t step 0;key_state key_scan(); // 按键扫描if(key_state KEY1_SHORT_PRESSED){// 按键1短按LOG(key1 short pressed.\n);}else if(key_state KEY1_LONG_PRESSED){// 按键1长按LOG(key1 long pressed.\n);}else if(key_state KEY2_SHORT_PRESSED){// 按键2短按LOG(key2 short pressed.\n);}else if(key_state KEY2_LONG_PRESSED){// 按键2长按LOG(key2 long pressed.\n);}else if(key_state KEY3_SHORT_PRESSED){// 按键3短按LOG(key3 short pressed.\n);}else if(key_state KEY3_LONG_PRESSED){// 按键3长按LOG(key3 long pressed.\n);}else if(key_state KEY4_SHORT_PRESSED){// 按键4短按LOG(key4 short pressed.\n);}else if(key_state KEY4_LONG_PRESSED){// 按键4长按LOG(key4 long pressed.\n);}
}/********************** 定时器配置用于定时扫描按键 *************************/
void TIMER2_IRQHandler(void)
{if(SET timer_interrupt_flag_get(TIMER2, TIMER_INT_UP)){/* clear channel 0 interrupt bit */timer_interrupt_flag_clear(TIMER2, TIMER_INT_UP);key_handle(); // 按键扫描并处理}
}void nvic_config(void)
{nvic_irq_enable(TIMER2_IRQn, 0, 0);
}void timer_config(void)
{/* ----------------------------------------------------------------------------TIMER2 Configuration: TIMER2CLK SystemCoreClock/18000 10KHz, the period is 1s(10/10000 1s).---------------------------------------------------------------------------- */timer_parameter_struct timer_initpara;/* enable the peripherals clock */rcu_periph_clock_enable(RCU_TIMER2);/* deinit a TIMER */timer_deinit(TIMER2);/* initialize TIMER init parameter struct */timer_struct_para_init(timer_initpara);/* TIMER2 configuration */timer_initpara.prescaler 18000 - 1; // 180MHz / 18000 10kHztimer_initpara.alignedmode TIMER_COUNTER_EDGE;timer_initpara.counterdirection TIMER_COUNTER_UP;timer_initpara.period 10 - 1; // 10 * 0.01ms 1mstimer_initpara.clockdivision TIMER_CKDIV_DIV1;timer_init(TIMER2, timer_initpara);/* enable the TIMER interrupt */timer_interrupt_enable(TIMER2, TIMER_INT_UP);/* enable a TIMER */timer_enable(TIMER2);
}void timer_user_init(void)
{/* configure the TIMER peripheral */timer_config();/* configure the TIMER2 interrupt */nvic_config();
}
key.h
#ifndef __KEY_H
#define __KEY_H#include gd32e50x.h
#include gd32e50x_gpio.h#define KEY1_SHORT_PRESSED 0
#define KEY2_SHORT_PRESSED 1
#define KEY3_SHORT_PRESSED 2
#define KEY4_SHORT_PRESSED 3
#define KEY1_LONG_PRESSED 4
#define KEY2_LONG_PRESSED 5
#define KEY3_LONG_PRESSED 6
#define KEY4_LONG_PRESSED 7#define KEY_PRESSED 0 // 按下时电平为0
#define KEY_RELEASED 1 // 按下时电平为1
#define KEY_SHORT_PRESSED 30 // 1ms x 30 30ms
#define KEY_LONG_PRESSED 1000 // 1ms x 1000 1s#define KEY1_CLOCK RCU_GPIOB
#define KEY1_PORT GPIOB
#define KEY1_PIN GPIO_PIN_12
#define KEY2_CLOCK RCU_GPIOB
#define KEY2_PORT GPIOB
#define KEY2_PIN GPIO_PIN_13
#define KEY3_CLOCK RCU_GPIOB
#define KEY3_PORT GPIOB
#define KEY3_PIN GPIO_PIN_14
#define KEY4_CLOCK RCU_GPIOB
#define KEY4_PORT GPIOB
#define KEY4_PIN GPIO_PIN_15#define READ_KEY1_STATE gpio_input_bit_get(KEY1_PORT, KEY1_PIN)
#define READ_KEY2_STATE gpio_input_bit_get(KEY2_PORT, KEY2_PIN)
#define READ_KEY3_STATE gpio_input_bit_get(KEY3_PORT, KEY3_PIN)
#define READ_KEY4_STATE gpio_input_bit_get(KEY4_PORT, KEY4_PIN)typedef struct
{uint16_t debounce;uint8_t status;
} key_t;void key_user_init(void);
int key_scan(void);#endif
main.c
#include main.h
#include uart.h
#include key.hint main(void)
{// systick_config();uart_user_init();key_user_init();printf(app init success.\n);while(1){}
}
mian.h
#ifndef MAIN_H
#define MAIN_H#include gd32e50x.h
#include gd32e50x_rcu.h
#include gd32e50x_gpio.h
#include systick.h
#include uart.h#define UART_DEBUG#ifdef UART_DEBUG#define DEBUG(format, ...) printf(format, ##__VA_ARGS__)#define LOG printf
#else#define DEBUG(format, ...)#define LOG(format, ...)
#endif#endif /* MAIN_H */
3 测试log 4 其他实现方式
详见我之前的博客以STM32为例实现按键的短按和长按