STC15单片机 - 按键单击和长按检测(外部中断)

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STC15单片机 - 按键单击和长按检测(外部中断)相关的知识,希望对你有一定的参考价值。

STC15单片机 - 按键单击和长按检测(外部中断)


  • ✨本案例来源于硬件家园的《STC15实战项目》中的内容,学习一下采用面向对象的编程思路,进行模块化设计,实现其功能。也方便在其他项目中进行移植使用。
  • 🌴测试芯片:IAP15W4K61S4单片机

🛠功能介绍

🔖采用按键扫描,利用定时器中断进行长按检测。单击LED(P34)电平翻转,长按2S以上,LED闪烁一次。

⛳引脚说明

  • 🌿按键:P32
  • 🌿LED:P34

模块代码

  • Key.c代码
/* Includes ------------------------------------------------------------------*/
#include <main.h>

/* Private define-------------------------------------------------------------*/
#define  KEY1_Status 	P32

/* Private variables----------------------------------------------------------*/

/* Private function prototypes------------------------------------------------*/
static void KEY_Detect(void);   //按钮开关检测

/* Public variables-----------------------------------------------------------*/
//结构体定义
KEY_t  KEY1 = FALSE,FALSE,FALSE,FALSE,KEY_Detect;      

/*
	* @name   KEY_Detect
	* @brief  按钮开关检测
	* @param  None
	* @retval None      
*/
static void KEY_Detect() 

	uint8_t i = (uint8_t)0;

	//单击检测
	if(KEY1.KEY_Flag == TRUE)
	
		KEY1.KEY_Flag = FALSE;
		
		EX0 = 0; //关中断
		
		if(KEY1_Status == 0)
		
			Public.Delay_ms(2);
			if(KEY1_Status == 0)
			
				KEY1.Click = TRUE;
			
		
	
	//长按检测
	if(KEY1.Click == TRUE)
	
		KEY1.Press = TRUE;
		for(i=0;i<200;i++)
		
			Public.Delay_ms(10);
			if(KEY1_Status == 1)
			
				KEY1.Press = FALSE;
				break; //提前跳出for循环
			
		
	
	
	按键动作
	//长按2s以上 -> 指示灯闪一下
	//单击       -> 指示灯状态翻转
	if(KEY1.Press == TRUE)
	
		LED_Run.LED_Flip();
		Public.Delay_ms(100);
		LED_Run.LED_Flip();
	
	else
	
		if(KEY1.Click == TRUE)
		
			LED_Run.LED_Flip();
//			P20 =~P20;
			
	
	
	KEY1.Press = FALSE; //清除长按标志位
	KEY1.Click = FALSE; //清除单击标志位
	
	EX0 = 1;  //开中断


/*
	* @name   INT0_isr
	* @brief  外部中断0服务函数
	* @param  None
	* @retval None      
*/
void INT0_isr() interrupt  0

	KEY1.KEY_Flag = TRUE;
	
	//LED_Run.LED_Flip();

/********************************************************
  End Of File
********************************************************/
  • Key.h代码
#ifndef __KEY_H__
#define __KEY_H__

//定义结构体类型
typedef struct

	uint8_t  volatile KEY_Flag;  //按键标志位
	uint8_t  Click;              //单击
	uint8_t  Double_Click;       //双击
	uint8_t  Press;              //长按
	void (*KEY_Detect)(void);    //按键检测
 KEY_t;

//结构体声明
extern KEY_t   KEY1;
/* extern variables-----------------------------------------------------------*/
	
/* extern function prototypes-------------------------------------------------*/


#endif
/********************************************************
  End Of File
********************************************************/
  • Timer0.h代码
#ifndef __Timer0_H__
#define __Timer0_H__

//定义枚举类型
typedef enum

	TIMER0_10mS  	= (uint16_t)2,
	TIMER0_50mS  	= (uint16_t)10,
	TIMER0_100mS	= (uint16_t)20,
	TIMER0_500mS	= (uint16_t)100,
	TIMER0_1S     = (uint16_t)200,
TIMER0_Value_t;

//定义结构体类型
typedef struct

  uint16_t volatile usMCU_Run_Timer;  //系统运行定时器
	void (*Timer0_Init)(void);          //定时器0初始化
 Timer0_t;

/* extern variables-----------------------------------------------------------*/
extern Timer0_t  Timer0;

#endif
/********************************************************
  End Of File
********************************************************/
  • Timer0.c代码
/* Includes ------------------------------------------------------------------*/
#include <main.h>

/* Private define-------------------------------------------------------------*/

/* Private variables----------------------------------------------------------*/

/* Private function prototypes------------------------------------------------*/      
static void Timer0_Init(void);//定时器0初始化

/* Public variables-----------------------------------------------------------*/
Timer0_t  Timer0 = 

	0,
	Timer0_Init
;

  • led.c代码
/* Includes ------------------------------------------------------------------*/
#include <main.h>

/* Private define-------------------------------------------------------------*/

/* Private variables----------------------------------------------------------*/
static void Run_LED_ON(void); 
static void Run_LED_OFF(void);
static void Run_LED_Flip(void);

/* Public variables-----------------------------------------------------------*/
LED_t LED_Run = 

	Run_LED_ON,
	Run_LED_OFF,
	Run_LED_Flip
;

/* Private function prototypes------------------------------------------------*/      

/*
	* @name   Run_LED_ON
	* @brief  关闭运行指示灯
	* @param  None
	* @retval None      
*/
static void Run_LED_ON()

	MCU_Run_LED = MCU_Run_LED_ON;


/*
	* @name   Run_LED_OFF
	* @brief  打开运行指示灯
	* @param  None
	* @retval None      
*/
static void Run_LED_OFF()

	MCU_Run_LED = MCU_Run_LED_OFF;


/*
	* @name   Run_LED_Flip
	* @brief  翻转充电指示灯
	* @param  None
	* @retval None      
*/
static void Run_LED_Flip()

	MCU_Run_LED = ~MCU_Run_LED;

/********************************************************
  End Of File
********************************************************/
  • led.h代码
#ifndef __LED_H__
#define __LED_H__

//RUN LED
#define   MCU_Run_LED			       P34
#define   MCU_Run_LED_ON 	       (bit)1
#define   MCU_Run_LED_OFF        (bit)0

//定义结构体类型
typedef struct

	void (*LED_ON)(void);     //打开
	void (*LED_OFF)(void);    //关闭
	void (*LED_Flip)(void);   //翻转
 LED_t;

/* extern variables-----------------------------------------------------------*/
extern LED_t  LED_Run;
/* extern function prototypes-------------------------------------------------*/

#endif
/********************************************************
  End Of File
********************************************************/

📚工程源码

链接:https://pan.baidu.com/s/1X5rs7FvfyhykKuPcAGiQQQ 
提取码:tv0i

以上是关于STC15单片机 - 按键单击和长按检测(外部中断)的主要内容,如果未能解决你的问题,请参考以下文章

6.STC15W408AS单片机外部中断

6.STC15W408AS单片机外部中断

6.STC15W408AS单片机外部中断

STC15单片机利用PCA在扩展外部中断和定时器以及脉宽测量的应用示例

5.STC15W408AS单片机按键输入

5.STC15W408AS单片机按键输入