EC修炼之道—按键的做法

        

在EC的各项功能中,按键的作用非常重要。机器上的PowerSwitch按键,亮度加减按键,声音加减按键,WIFI&Bluetooth开关等,都有可能用到按键功能。

         按键的做法有两种:一是使用中断的方式;二是使用轮循GPIO的电平状态来做按键功能。这篇文章的重点在于介绍轮循的方式,因为第一种方式让我吃了不少苦头,现在我都一般不会采用它。

 

1 中断方式

         这是做按键功能的正统方式,做的时候一板一眼,上学读书的时候也是这么做的。分为以下几个步骤:第一步,想使用哪个GPIO做按键,就使能相应GPIO的中断,并设置相应的中断方式,即电平或边沿触发;第二步,在中断函数中,关中断清中断标志并延时去抖,然后判断电平状态,如果无误,则调用该按键的功能函数;第三步,开中断,迎接下一步的中断。

 

2 轮循GPIO电平状态

         这是我大比较喜欢的方式,当我一接触到这种方式时,便将以前的代码全改成这种方式。甚至连其它的8051单片机程序,我都这样做。

 

2.1 优势

         这种方法相对第1种方式,占据比较大的优势。首先,它不会用程序延时,所以不会拖慢其他模块的功能;其次,编程相对简单,只要逻辑层做起来,留出一个数据数组给OEM层来使用,填一个数组总比写程序失误率要小得多;再者,有很多按键功能需要repeat,用中断的方式没法准确控制repeat的时间,而且延时得太多,用轮循的方式可以轻而易举完美地做到这个功能(我自己加的)。

 

2.2  具体实现方式       

我们来看一下OEM接口:

typedefvolatile struct _EVENT_DESCRIPTOR

{

    BYTE PortPin;        //使用的GPI

    BYTE Bounce;     // 去抖延时时间

}EVENT_DESCRIPTOR;

 

static constEVENT_DESCRIPTOR Events_Table[] =

{

 

    {PWRBTN_IN, 10},         //PowerSwitch

    {VOLUME_UP, 10},         //声音加

                   {VOLUME_DOWN, 10},     //声音减

};

 

 

签了NDA,就要为别人保密。扫描按键的代码就不贴了,画张流程图吧。

流程图:


EC修炼之道—按键的做法_第1张图片


2.3 加repeat功能

         Vendor毕竟不是OEM,并不知道OEM厂商的具体需求,所以没有加入repeat功能,但基于vendor的codebase,加repeat功能并不困难。

         首先改变结构体如下:

typedefvolatile struct _EVENT_DESCRIPTOR

{

    BYTE PortPin;        //使用的GPI

    BYTE Bounce;     // 去抖延时时间

                   BYTE DelayToRepeat;      //开始Repeat的时间

                   BYTE PeroidRepeat;                  //Repeat的间隔时间

}EVENT_DESCRIPTOR;

 

static constEVENT_DESCRIPTOR Events_Table[] =

{

 

    {PWRBTN_IN, 10,0,0},         //PowerSwitch

    {VOLUME_UP, 10,50,10},              //声音加

                   {VOLUME_DOWN, 10,50,10},   //声音减

};

然后再改变一下扫描按键的代码,需要加三部分:一,在按键电平状态不一致时,除了保存上一电平外,还要清除一下保存DelayToRepeat和PeroidRepeat值的计数数组;二,在去拌时间结束后,要判断当前状态是否为ACTIVE和是否需要Repeat功能,如果这两条件满足,则将DelayToRepeat赋值给计数数组;三,计数数组计数结束后,执行按键功能函数,并将PeroidRepeat值重新赋给计数数组。


你可能感兴趣的:(EC)