【STC15】前后台方式实现按键的长按检测(面向对象)
数据结构(结构体定义借鉴了面向对象思想):
#ifndef __KEY_H_
#define __KEY_H_
//定义按键引脚
#define KEY1_State P32
//定义结构体类型
typedef struct
{
uint8_t volatile KEY_Flag; //按键标志位
uint8_t Click; //单击
uint8_t Double_Click; //双击
uint8_t Press; //长按
void (*KEY_Detect)();
}KEY_t;
/* extern variables-----------------------------------------------------------*/
extern KEY_t KEY1;
/* extern function prototypes-------------------------------------------------*/
#endif
/********************************************************
End Of File
********************************************************/
后台:中断
/*
* @name INT0_isr
* @brief 外部中断0中断处理函数
* @param None
* @retval None
*/
void INT0_isr() interrupt 0
{
KEY1.KEY_Flag = TRUE;
//Run_LED.Run_LED_Flip();
}
前台:轮询
/* Includes ------------------------------------------------------------------*/
#include <main.h>
/* Private define-------------------------------------------------------------*/
/* Private variables----------------------------------------------------------*/
static void KEY_Detect();
/* Public variables-----------------------------------------------------------*/
KEY_t KEY1 = {FALSE,FALSE,FALSE,FALSE,KEY_Detect};
/* Private function prototypes------------------------------------------------*/
/*
* @name KEY_Detect
* @brief 按键检测
* @param None
* @retval None
*/
static void KEY_Detect()
{
uint8_t i;
//长按检测
if(KEY1.KEY_FLAG == TRUE)
{
KEY1.Press = TRUE; //如果有按键按下,默认会进行长按
for(i = 0;i<200;i++) //每次循环延时10ms,即延时2秒
{
Public.Delay_ms(10);
if(KEY1_State == 1) //如果这期间按键松开了,则达不到长按的条件
{
KEY1.Press = FALSE; //长按标志位清0
break; //提前结束延时
}
}
}
}
/*
* @name KEY_Act
* @brief 按键功能执行
* @param None
* @retval None
*/
static void KEY_Act()
{
//按键功能
//单击 -> 运行指示灯翻转
//长按 -> 运行指示灯闪一下
if(KEY1.Press == TRUE)
{
Run_LED.Run_LED_Flip();
Public.Delay_ms(100);
Run_LED.Run_LED_Flip();
}
else
{
if(KEY1.Click == TRUE)
{
Run_LED.Run_LED_Flip();
}
}
KEY1.Click = FALSE;
KEY1.Press = FALSE;
EX0 = 1; //打开中断
}
主函数:
/*
* @name main
* @brief 主函数
* @param void
* @retval int
*/
int main(void)
{
//系统初始化
Hradware.Sys_Init();
//系统主循环
while(1)
{
KEY1.KEY_Detect();//按键检测
KEY1.KEY_Act();//按键功能执行
}
}
扩展:单前台轮询方式实现多按键检测:
if(KEY_IO != 0xFF) //检测到有按键按下
{
DelayNms (20); //延时20毫秒(严重影响单片机的运行效率)
if (KEY_IO !=0xFF) //确认按键按下
{
switch (KEY_IO)
{
case 0xFE: KeyValue=1 ; break;
case 0xFD: KeyValue=2 ; break;
default: KeyValue=0 ; break;
}
}
}
参考文章:
原文链接:https://blog.csdn.net/weixin_46251230/article/details/126659466