今天介绍一下z-stack的key驱动程序。先看一下我板子上的按键连接图
可以看到总共有六个按键,不算复位键,up、down、left、right四个为摇杆的方向键,PUSH为摇杆的中心键,这个五个键接的是P20,通过接到P06的AD转换功能来判断出是哪个按键按下。当按下五个键中任何一个时,P20就变为高电平,在上升沿触发中断标志。TI官方的板子跟这个电路图有点不同,z-stack里面key驱动是按照TI的官方板子写的,我把其中需要改的地方改过来了,等哈会提到。
先看hal_key.h这个头文件
#define HAL_KEY_SW_1 0x01 // Joystick up
#define HAL_KEY_SW_2 0x02 // Joystick right
#define HAL_KEY_SW_5 0x04 // Joystick center
#define HAL_KEY_SW_4 0x08 // Joystick left
#define HAL_KEY_SW_3 0x10 // Joystick down P06
#define HAL_KEY_SW_6 0x20 // Button S5 if available
#define HAL_KEY_SW_7 0x40 // Button S2 if available P05 板子上是P0.5
这个源程序的定义,我板子上没有SW6,其中SW7对应的是板子的Button S2,如上图连接的是P05,这里对按键采用位图的定义,即某一位对应一个按键,对后面的按键的处理有很好的帮助,值得借鉴。
然后定义了key回调函数的函数指针typedef void (*halKeyCBack_t) (uint8 keys, uint8 state);参数keys即为上面按键定义的组合,如keys=HAL_KEY_SW_1|HAL_KEY_SW_5,参数state为keys的状态,在上面可以看到这两个定义
/* Key state - shift or normal */
#define HAL_KEY_STATE_NORMAL 0x00
#define HAL_KEY_STATE_SHIFT 0x01
HAL_KEY_STATE_NORMAL对应普通按键,HAL_KEY_STATE_SHIFT对应的摇杆的按键。接下来看下hal_key.c这个源文件。先看下这个两个宏定义
#define HAL_KEY_DEBOUNCE_VALUE 25 //中断方式 中断之后延迟25ms进入按键处理程序
#define HAL_KEY_POLLING_VALUE 100 //查询方式 每100ms检查是否有按键按下
正像我后面作出的注释,z-stack对按键的处理采用了中断和查询方式。中断方式和查询方式有一半相同点有一半不同,相同的是在按键按下之后过某个设定的时间后设置事件标志HAL_KEY_EVENT,然后在下一次系统轮询中对此事件进行处理调用相关的按键处理函数,不同的是对于查询方式,CPU需要定期检查按键的状态,当检测到按键按下延迟100ms向HAL层发出HAL_KEY_EVENT事件,对于中断方式,当按键按下时,则立刻发出HAL_KEY_EVENT事件,不需要CPU的检查,中断方式比查询方式实时性好。这两个宏定义就是针对两种不同key处理方式而设置的延迟时间!在后面再讲key的处理过程。先看看key驱动都是什么东东!
/* SW_6 is at P0.1 */
/*板子上面没有SW_6,改成SW_7 at P0.5*/
#define HAL_KEY_SW_7_PORT P0
#define HAL_KEY_SW_7_BIT BV(5)
#define HAL_KEY_SW_7_SEL P0SEL
#define HAL_KEY_SW_7_DIR P0DIR
对于我的板子 上面没有SW_6而SW_7对应于S2 at P0.5,所以讲所有的HAL_KEY_SW_6_X改成HAL_KEY_SW_7_X,且之前的设置是在P01,而SW_7是在P05,所以相关的寄存器设置都相应改过来。这里有一大堆宏定义看datasheet,对于学过单片机的同学就很简单,这里不一一列举出来了。
看一下几个全局变量halKeySavedKeys /* used to store previous key state in polling mode */如注释,用于查询方式的保存之前按键的状态。pHalKey