2335|0

931

帖子

3

TA的资源

纯净的硅(中级)

楼主
 

使用定时器的长短按键 [复制链接]

    在我提交的作品当中使用的是在主循环中轮询的方式来获得长短键值,简单实用,已经能够满足项目需要。正如广大坛友指出的那样,轮询方法在读取按键长短时MCU不能做其他事情,效率太低,在一些场合还会对MCU处理其他事务造成影响,不少坛友建议采用定时器的方法,但当时为了不影响项目作品提交进度,就先将就使用轮询法了。这段时间稍得空闲,我对项目代码中的按键获得进行优化,使用了定时器累计键值的方式来识别长短按键,经过测试,完全达到预计目的。

    使用定时器法的基本思路是设置两个全局变量keys和keyf,前者计数,后者作按键结束标志,定时器的定时时间为10毫秒,keys是8位的变量,最大计数为255,可以分辨2.55秒之内的按键时间(大于2.55秒则按2.55秒计算),通过实验,快按快松(点击)按键时返回的键值通常在10左右,按下后再松开(短按)返回的键值约在30~40左右,按下后稍等片刻再松开(中按)返回的键值约在60~90左右,按下后数两下再松开(长按)返回的键值大约在120~180左右,按下后数四下再松开(超长按)返回的键值大约会大于200,在我的项目中,键值与功能的对应关系见下表:

keys 分类 mode>6 chick=1 mode=1~6
报警设置 查询 日历设置
<20 点按 慢增 下翻 慢增
20~49 短按 快增 上翻 快增
50~99 中按 轮换   轮换
100~199 长按   进退  
>200 超长按 进退    

   

    下面是定时器2配置的代码:

void timer_config(void)
{
    /* -----------------------------------------------------------------------
    TIMER2CLK is 100KHz定时器2 CLK为100kHz

    TIMER2 channel0 duty cycle = (25000/ 50000)* 100  = 50%
    ----------------------------------------------------------------------- */
    timer_oc_parameter_struct timer_ocintpara; //定义数据结构
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(RCU_TIMER2);       //开启时钟

    timer_deinit(TIMER2);                      //指定定时器

    /* TIMER configuration 定时器配置*/
    timer_initpara.prescaler         = 719;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 999;            //定时10毫秒
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER2,&timer_initpara);

    /* configurate CH0 in PWM mode0 在PWM模式0中配置CH0*/
    timer_interrupt_enable(TIMER2, TIMER_INT_UP); //Enable TIMER2
    nvic_irq_enable(TIMER2_IRQn, 0);              //Set priority to 0(0-2)

    /* auto-reload preload enable 自动重新加载预加载启用*/
    timer_auto_reload_shadow_enable(TIMER2);
    /* auto-reload preload enable */
    timer_enable(TIMER2);
}

    在我的项目中,定时器2除按键计数外还兼作报警声延时作用,详见下面的中断处理代码:

//The interrupt handler function of tmer2//
void TIMER2_IRQHandler(void)
{
    if(RESET != timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_UP))
    {

		if(time>0)      //在报警状态,延时减1(10毫秒)
			time--;

		if(keyf==0)     //按键处理等待状态(keyf=1时,上次按键尚未处理完毕)
		{
			if(1==gd_eval_key_state_get(KEY_WAKEUP)) //按键按下
			{
				if(keys<255)
					keys++;  //按键计数
			}
			else
			{
			    if(keys>0)
					keyf = 1;//置按键松开标志
			}
		}

    }
    timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
}

    下面是在主循环中检测按键的代码,当检测到有按键事件时除调用按键处理函数外,还要将按键值归零并置按键事件处理完毕标志:

		//	轮询按键处理
        if(keyf > 0){          //有键按下
			key_processing();
			keys = 0;
			keyf = 0;          //置按键处理完毕标志
		}

 

此帖出自GD32 MCU论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表