瑞萨单片机之外部中断实现按键的长按与短按(二)

最近项目上用到瑞萨单片机,把自己的学习过程记录一下,由于自己是第一次接触瑞萨单片机,一开始还是踩了不少坑。这里我用外部中断实现按键的长按用短按功能

一、实现原理

  1. 首先设置外中断触发方式为下降沿触发。(初始化已设置)
  2. 按键按下触发中断,此时记录时间,同时将触发方式改为上升沿触发。
  3. 按键释放,再次触发上升沿(此时触发方式为上升沿触发)。
  4. 主程序中判断按下的时间长短做相应的动作,此时将触发方式又重新改为下降沿触发。

二、具体实现

2.1 封装按键结构

typedef struct KEY_STRUCT
{
        u8 key_status;     /*按键状态*/
		u8 key_press_time; /*按键按下时间*/
		u8 key_lock;       /*按键锁*/
		u8 key_num;        /*按键按下计数*/
};

2.2 瑞萨单片机外中断配置

根据前面的章节的介绍,这里主要是对外设IO引脚功能的映射,INTP2 对应的是 P122,如果选择上升沿触发最好把IO 加个下拉电阻拉低,如果选择下降沿触发最好把IO 加个上拉电阻拉搞,
在这里插入图片描述

在CS+中配置 外中断触发方式,然后点击生成代码即可
在这里插入图片描述

主要把INTP2 外部中断配置为下降沿触发

void R_INTC_Create(void)
{
    PMK0 = 1U;    /* disable INTP0 operation */
    PIF0 = 0U;    /* clear INTP0 interrupt flag */
    PMK1 = 1U;    /* disable INTP1 operation */
    PIF1 = 0U;    /* clear INTP1 interrupt flag */
    PMK2 = 1U;    /* disable INTP2 operation */
    PIF2 = 0U;    /* clear INTP2 interrupt flag */
    PMK3 = 1U;    /* disable INTP3 operation */
    PIF3 = 0U;    /* clear INTP3 interrupt flag */
    /* Set INTP0 level 2 priority */
    PPR10 = 1U;
    PPR00 = 0U;
    /* Set INTP2 level 2 priority */
    PPR12 = 1U;
    PPR02 = 0U;
    EGN0 = _04_INTP2_EDGE_FALLING_SEL;
    EGP0 = _01_INTP0_EDGE_RISING_SEL;
}

2.3 外部中断 & 定时器中断函数中 业务逻辑

  1. 按键按下 对key_struct.key_press_time 清零,按压状态置1,说明按键按下,这一步主要是对按压 初始时间清零,在定时器中对key_struct.key_press_time进行累加。
  2. 按键按下后 将触发方式改为上升沿触发。
  3. 按键释放后,中断又被触发,此时进入的是else 语句中,这里只把按键key_struct.key_status置0,这样在定时器中断就不会对key_struct.key_press_time中再进行累加了,这样一来我们只需要在主程序中判断按压时间的长短动作就可以了。
  4. 按键释放了,别忘了把触发方式又改回原来的下降沿触发。
外部中断中:

__interrupt static void r_intc2_interrupt(void)
{
	 if(key_struct.key_status==0)  //按键按下  下降沿触发
		{
		  	 key_struct.key_press_time=0;
			 key_struct.key_status=1;
			 key_struct.key_lock=0;			
			 EGP0 |= _04_INTP2_EDGE_RISING_SEL;  //上升沿触发  所有外中断都是这个寄存器,最好用 |
		}
		else                                 //按键释放  上升沿触发
		{
			  key_struct.key_status==0;
              key_struct.key_lock=1;		
		  	  EGN0 |= _04_INTP2_EDGE_FALLING_SEL;  //下降沿触发
		}
			
}

定时中断中 按压时间每1s 加一次

定时器中断中:

	if(key_struct.key_status) //按键按压计时
	{
	   	key_struct.key_press_time++;  //按键按压时间			
	}

2.4 例子

#define SHORT_PRESS   2   //两秒
#define LONG_PRESS    5   //5秒

void  key_task(void)
{
	 if((key_struct.key_press_time<=SHORT_PRESS) && (key_struct.key_lock)) //小于2s 认为是短按
	 {
		key_struct.key_press_time=0;
		key_struct.key_lock=0;

	    key_struct.key_num +=1;		
	    if(key_struct.key_num>=4) 
        {
	    	key_struct.key_num=0;
   	    }		
	 }
	  else if((key_struct.key_press_time>=LONG_PRESS) && (key_struct.key_lock)) //大于5s 认为是长按
     {
	    key_struct.key_num=4;
	    
	   	key_struct.key_press_time=0;
		key_struct.key_lock=0;
	 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值