本文目录
- 本篇前言
- 代码思路
- 实操练习
本篇前言
今天接着上篇与大家继续分享软件方面关于按键事件的处理,上篇软件01篇已提到整个软件框架时基的处理,其中提到了关于按键的处理,这篇将具体地介绍按键处理的思路与实例。
话不多说,加个封面图直接开始。
代码思路
按键扫描函数思路:
1.判断GPIO按键按下。
2.记录按下时间,判断按下时间是否满足按键消抖时间(短按时间)。
3.满足短按时间后,标记按键按下标志位。
4.随着按下时长是否满足长按时间,并且按键是首次使用(防止一直进行这长按操作)。
5.判断按键是否释放,释放后,根据按下标记与按键是否为首次使用标记,是否执行短按操作,接着,重置按下时间、按下标记、按键使用标记。
实操练习
设计三个按键各自按下的短按(50ms),长按(3s)的处理。
单片机硬件平台不要求,可移植到任何平台。
按键扫描函数zj_app_key_scan.c
#define FALSE 0
#define TRUE 0
#define BSP_KEY_1_GPIO_PIN GPIO_PIN_3
#define BSP_KEY_1_GPIO_PORT GPIOB
#define BSP_KEY_1_GET !GPIO_ReadInputDataBit(BSP_KEY_1_GPIO_PORT,BSP_KEY_1_GPIO_PIN)
#define BSP_KEY_2_GPIO_PIN GPIO_PIN_4
#define BSP_KEY_2_GPIO_PORT GPIOB
#define BSP_KEY_2_GET !GPIO_ReadInputDataBit(BSP_KEY_2_GPIO_PORT,BSP_KEY_2_GPIO_PIN)
#define BSP_KEY_3_GPIO_PIN GPIO_PIN_5
#define BSP_KEY_3_GPIO_PORT GPIOB
#define BSP_KEY_3_GET !GPIO_ReadInputDataBit(BSP_KEY_3_GPIO_PORT,BSP_KEY_3_GPIO_PIN)
#define KEY_1_LONG_CHECK_MS 3000
#define KEY_1_SHORT_CHECK_MS 50
#define KEY_2_LONG_CHECK_MS 3000
#define KEY_2_SHORT_CHECK_MS 50
#define KEY_3_LONG_CHECK_MS 3000
#define KEY_3_SHORT_CHECK_MS 50
uint16_t eKey_1_press_time = 0;
uint8_t eKey_1_press_flag = 0;
uint8_t eKey_1_used_flag = 0;
uint16_t eKey_2_press_time = 0;
uint8_t eKey_2_press_flag = 0;
uint8_t eKey_2_used_flag = 0;
uint16_t eKey_3_press_time = 0;
uint8_t eKey_3_press_flag = 0;
uint8_t eKey_3_used_flag = 0;
static void zj_app_key_1_short(void)
{
//这里写1号按键的短按处理
}
static void zj_app_key_1_long(void)
{
//这里写1号按键的长按处理
}
static void zj_app_key_2_short(void)
{
//这里写2号按键的短按处理
}
static void zj_app_key_2_long(void)
{
//这里写2号按键的长按处理
}
static void zj_app_key_3_short(void)
{
//这里写3号按键的短按处理
}
static void zj_app_key_3_long(void)
{
//这里写3号按键的长按处理
}
static void zj_app_key_1_10ms_scan(void)
{
if(BSP_KEY_1_GET)
{
eKey_1_press_time++;
if(eKey_1_press_time * 10 >= KEY_1_SHORT_CHECK_MS) //防抖50ms
eKey_1_press_flag = TRUE; //标记有按下
}
else
{
//松手处理
if(eKey_1_press_flag && eKey_1_used_flag == FALSE) //不足长按时间3S
zj_app_key_1_short(); //短按处理
//恢复按键
eKey_1_press_time = 0;
eKey_1_press_flag = FALSE;
eKey_1_used_flag = FALSE;
}
if(eKey_1_press_time * 10 >= KEY_1_LONG_CHECK_MS && eKey_1_used_flag == FALSE)//满足长按时间3S,只有效一次长按
{
zj_app_key_1_long();//长按处理
eKey_1_used_flag = TRUE;
}
}
static void zj_app_key_2_10ms_scan(void)
{
if(BSP_KEY_2_GET)
{
eKey_2_press_time++;
if(eKey_2_press_time * 10 >= KEY_2_SHORT_CHECK_MS) //防抖50ms
eKey_2_press_flag = TRUE; //标记有按下
}
else
{
//松手处理
if(eKey_2_press_flag && eKey_2_used_flag == FALSE) //不足长按时间3S
zj_app_key_2_short(); //短按处理
//恢复按键
eKey_2_press_time = 0;
eKey_2_press_flag = FALSE;
eKey_2_used_flag = FALSE;
}
if(eKey_2_press_time * 10 >= KEY_2_LONG_CHECK_MS && eKey_2_used_flag == FALSE)//满足长按时间3S,只有效一次长按
{
zj_app_key_2_long();//长按处理
eKey_2_used_flag = TRUE;
}
}
static void zj_app_key_3_10ms_scan(void)
{
if(BSP_KEY_3_GET)
{
eKey_3_press_time++;
if(eKey_3_press_time * 10 >= KEY_3_SHORT_CHECK_MS) //防抖50ms
eKey_3_press_flag = TRUE; //标记有按下
}
else
{
//松手处理
if(eKey_3_press_flag && eKey_3_used_flag == FALSE) //不足长按时间3S
zj_app_key_3_short(); //短按处理
//恢复按键
eKey_3_press_time = 0;
eKey_3_press_flag = FALSE;
eKey_3_used_flag = FALSE;
}
if(eKey_3_press_time * 10 >= KEY_3_LONG_CHECK_MS && eKey_3_used_flag == FALSE)//满足长按时间3S,只有效一次长按
{
zj_app_key_3_long();//长按处理
eKey_3_used_flag = TRUE;
}
}
void zj_app_key_scan_10ms_process(void)
{
zj_app_key_1_10ms_scan();
zj_app_key_2_10ms_scan();
zj_app_key_3_10ms_scan();
}
代码的移植只需要注意各个单片机的IO初始化,按键判断高低电平以及对应的库函数即可,将zj_app_key_scan_10ms_process(void)声明后放在10ms时基处理调用即可,按键的具体操作在各自的短按处理函数、长按处理函数设计即可。文章来源:https://www.toymoban.com/news/detail-767892.html
小弟感谢大家的关注!
(利他之心,原创分享)文章来源地址https://www.toymoban.com/news/detail-767892.html
到了这里,关于(软件02)单片机按键处理,区分短按与长按的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!