我做操作的芯片是TiCC2530。就不考虑Zstack协议栈而言,如果要用到按键,无非是中断或者查询两种方式。
查询方式是通过查询按键对应I/O口的状态来判断按键的状态,从而进行相应的处理。
外部中断的方式是使能按键对应得I/O口的中断,当I/O口的状态改变时触发中断,从而在相应的中断处理函数中进行处理。
万变不离其宗,Zigbee协议栈的按键操作本质上也是对于基本查询方式和终端方式的封装。对于查询方式我们关键要找到它是如何配置引脚的功能/输入输出/上拉下拉,以及是如何查询引脚状态的,对于中断方式关键是配置相应引脚的中断和相应的中断处理函数。
首先是ZMain.c文件中的两个函数涉及到了按键的配置,分别是InitBoard( )和 HalDriverInit()其中InitBoard()调用了两次
// Initialize board I/O
InitBoard( OB_COLD );
右键GO TO,其中参数OB_COLD是一个宏#define OB_COLD 0
void InitBoard( uint8 level )
{
if ( level == OB_COLD )
{
// Interrupts off
osal_int_disable( INTS_ALL );
// Turn all LEDs off
HalLedSet( HAL_LED_ALL, HAL_LED_MODE_OFF );
// Check for Brown-Out reset
ChkReset();
}
else // !OB_COLD
{
/* Initialize Key stuff */
OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;
HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
}
}
第一个if是成立的,所以关闭所有的中断并关闭LED。我们回到main()函数
// Initialze HAL drivers
HalDriverInit();
右键GO TO,找到了按键的初始化函数HalKeyInit()
/* KEY */
#if (defined HAL_KEY) && (HAL_KEY == TRUE)
HalKeyInit();
#endif
右键GO TO ,这里主要是配置了P0SEL、P0DIR和P1SEL、P1DIR为通用和输入。
void HalKeyInit( void )
{
/* Initialize previous key to 0 */
halKeySavedKeys = 0; //默认当前键值为0
HAL_KEY_SW_6_SEL &= ~(HAL_KEY_SW_6_BIT); /* Set pin function to GPIO */ //P0.1设置为通用
HAL_KEY_SW_6_DIR &= ~(HAL_KEY_SW_6_BIT); /* Set pin direction to Input */ //P0.1设置为输入
HAL_KEY_JOY_MOVE_SEL &= ~(HAL_KEY_JOY_MOVE_BIT); /* Set pin function to GPIO */ //P2.0设置为通用
HAL_KEY_JOY_MOVE_DIR &= ~(HAL_KEY_JOY_MOVE_BIT); /* Set pin direction to Input */ //P2.0设置为输入
/* Initialize callback function */
pHalKeyProcessFunction = NULL; //默认无回调函数
/* Start with key is not configured */
HalKeyConfigured = FALSE;
}
GO TO HAL_KEY_SW_6_SEL发现就是P0SEL寄存器,到这里终于揭开了Zigbee包装的一角,其中寄存器的配置是也是以宏的方式给出的
#define HAL_KEY_SW_6_PORT P0
#define HAL_KEY_SW_6_BIT BV(1)
#define HAL_KEY_SW_6_SEL P0SEL
#define HAL_KEY_SW_6_DIR P0DIR
#ifndef BV
#define BV(n) (1 << (n))
#endif
/* Joy stick move at P2.0 */
#define HAL_KEY_JOY_MOVE_PORT P2
#define HAL_KEY_JO