【雅特力AT32-KEY-TMR】定时器实现延时消抖与长短按键判断(话不多说上源码)

#include "Timer.h"

/* 进行长短按键判断时,判断步骤0,1,2 ,对应VT_Key.key_sta */
#define KEY_STA_0	0			// 按键按下
#define KEY_STA_1	1			// 确认按键按下
#define KEY_STA_2	2			// 判断长短按键

/* 按键结构体 */
struct MY_Key
{
	uint8_t 	key_sta;		// 步骤标志位
	bool 		key_single;		// 按键状态位
	bool 		key_short;		// 短按键标志位
	bool 		key_long;		// 长按键标志位
	uint8_t 	key_time;		// 软件计时(ms)
};

uint8_t Count_10ms 			=  0;
bool 	Count_500ms_flag 	=  0;

struct 	MY_Key User_Key		=  {0};
uint8_t short_key_sta 		=  0;		// 短按键次数


/**
  * @brief  tmr1 configuration.
  * @param  none
  * @retval none
  * 配置定时器1,使其以1Hz的频率触发溢出中断,并在溢出时执行相应的中断处理程序
  */
void tmr1_config(void)
{
  crm_clocks_freq_type crm_clocks_freq_struct = {0};	//定义并初始化系统时钟频率结构体

  /* get system clock */
  crm_clocks_freq_get(&crm_clocks_freq_struct);			//获取系统时钟频率

  crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);	//启用定时器1的外设时钟:144MHZ

  /* (systemclock / (144M/144)) / 10000 = 100Hz(0.001s=10ms) */
  // system_core_clock 高速内部时钟(high speed internal clock) HICK_VALUE 的频率为8MHz!!!!!
  tmr_base_init(TMR1, 9999, 143);	//初始化定时器基本参数:能推出 TMR1 的时钟源为系统时钟
  tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);						//设置定时器计数方向为	向上计数
  tmr_clock_source_div_set(TMR1, TMR_CLOCK_DIV1);			//设置定时器时钟源分频

  
  tmr_interrupt_enable(TMR1, TMR_OVF_INT, TRUE);			//使能定时器1的 溢出 中断
  nvic_irq_enable(TMR1_OVF_TMR10_IRQn, 0, 0);				//使能定时器1的 NVIC 中断
}

/**
  * @brief  tmr1 interrupt handler
  * @param  none
  * @retval none
  */
void TMR1_OVF_TMR10_IRQHandler(void)
{
	//检查定时器溢出中断标志位是否被设置:定时中断
	if(tmr_interrupt_flag_get(TMR1,TMR_OVF_FLAG) != RESET)	
	{
		at32_led_toggle(LED2);		// 100次中断/秒  = 0.01s(10ms)/次
	  
		/* delay 500ms */
		Count_10ms++;
		if(Count_10ms == 50)			
		{
			at32_led_toggle(LED3);	//0.01s(10ms) * 50 = 500ms
			
			Count_500ms_flag = true;

			Count_10ms = 0;
		}
		
		/* Key Handle */
		User_Key.key_single = at32_button_state();		// 获取按键状态
		/* 判断步骤进行到哪一步:定时器每10ms进入一次中断(switch)   */
		switch(User_Key.key_sta)						
		{
			/* 步骤一:按键按下,计时清零,进入步骤1                  */
			case KEY_STA_0:								
				if(User_Key.key_single == RESET)		
				{
					User_Key.key_time = 0;
					User_Key.key_sta  = KEY_STA_1;
					
				}
			break;
			/* 步骤二:确认按键按下,进入步骤2,否则进入步骤1         */
			case KEY_STA_1:
				if(User_Key.key_single == RESET)		
				{
					User_Key.key_sta = KEY_STA_2;
				}
				else
				{
					User_Key.key_sta = KEY_STA_0;
				}
			break;
			/* 步骤三:长短按键界限可自定义,若按键仍然按下,开始计时 */
			case KEY_STA_2:
				if(User_Key.key_single == SET)			
				{
					if(User_Key.key_time <= 100)		// 长短按键时间界限:100*10ms
					{	
						at32_led_toggle(LED4);
						
						User_Key.key_short 	= 	1;
						User_Key.key_sta 	= 	0;
					}
					User_Key.key_time = 0;				
				}
				else
				{		
					User_Key.key_time++;
					if(User_Key.key_time > 100)
					{	
						User_Key.key_long = 1;
					}
				}
			break;
			default:
				//Serial_SendString("Unknown state\n");
			break;
		}
		tmr_flag_clear(TMR1,TMR_OVF_FLAG);
	}
}

/* 获取并更新500ms标志位*/
bool Get_500ms(void)
{
	bool Retuen_500ms_flag = Count_500ms_flag;
	Count_500ms_flag = false;
	
	return Retuen_500ms_flag;
}

/* 获取并更新按键次数*/
uint8_t Get_short_key_sta(void)
{
	bool short_key_flag = User_Key.key_short;
	
	if(short_key_flag == true)	// 短按键标志位判断
	{
		short_key_sta++;
		if(short_key_sta == 3)	// 计数范围0~2
		{
			short_key_sta = 0;
		}
		/* 测试 */
//		char Print_Text[30] = {0};
//		sprintf(Print_Text, "short_key_sta:%d \r\n", short_key_sta);
//		Serial_SendArray((uint8_t *)Print_Text, strlen(Print_Text));
	}
	
	/* 长短按键标志位均清零 */	
	User_Key.key_short 	=  false;
	User_Key.key_long 	=  false;
	
	short_key_flag 		=  false;
	
	return short_key_sta;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值