(配套源码、软件、开发板等资源,可移步博客同名QQ群:拿破仑ZigBee)
(1)上面已经提及,Z-Stack协议栈中默认使用的就是“轮询模式”,第一次触发硬件抽象层任务(Hal_TaskID)中的按键查询事件(HAL_KEY_EVENT)后,随即也就触发了间隔为100ms(1秒10次)的定时按键检测(循环调用HalKeyPoll( )),故称为“轮询模式”:
uint16 Hal_ProcessEvent( uint8 task_id, uint16 events )
{
......
if (events & HAL_KEY_EVENT)
{
#if (defined HAL_KEY) && (HAL_KEY == TRUE)
/* Check for keys */
HalKeyPoll();
/* if interrupt disabled, do next polling */
if (!Hal_KeyIntEnable)
{
osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 100);
}
#endif // HAL_KEY
return events ^ HAL_KEY_EVENT;
}
......
}
(2)在HalKeyPoll( )函数中,对各个定义的按键状态做完检测之后,即调用前面指定的按键回调函数OnBoard_KeyCallback( ),对键值做进一步处理:
void HalKeyPoll (void)
{
......
/* Invoke Callback if new keys were depressed */
if (keys && (pHalKeyProcessFunction))
{
(pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);
}
......
}
OnBoard_KeyCallback( )函数的代码如下,可见其中又进一步调用了OnBoard_SendKeys( ):
void OnBoard_KeyCallback ( uint8 keys, uint8 state )
{
uint8 shift;
(void)state;
shift = (keys & HAL_KEY_SW_6) ? true : false;
if ( OnBoard_SendKeys( keys, shift ) != ZSuccess )
{
......
}
}
在OnBoard_SendKeys( )函数中,最终将键值(keys)封装成了一个keyChange_t类型的数据包,发送至了registeredKeysTaskID任务:
uint8 OnBoard_SendKeys( uint8 keys, uint8 state )
{
......
// Send the address to the task
msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) );
if ( msgPtr )
{
msgPtr->hdr.event = KEY_CHANGE;
msgPtr->state = state;
msgPtr->keys = keys;
osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );
}
......
}
至于registeredKeysTaskID,其实就是在RegisterForKeys( )函数中被赋值指定的:
uint8 RegisterForKeys( uint8 task_id )
{
// Allow only the first task
if ( registeredKeysTaskID == NO_TASK_ID )
{
registeredKeysTaskID = task_id;
return ( true );
}
else
return ( false );
}
而调用RegisterForKeys( )函数,则是在我们的应用层任务ProjectApp中,也就是所谓的“注册按键”:
void ProjectApp_Init( uint8 task_id )
{
ProjectApp_TaskID = task_id;
......
RegisterForKeys( ProjectApp_TaskID );// Register for all key events - This app will handle all key events
......
}
(3)紧接着,我们的应用层任务ProjectApp就会收到键值所在的数据包,具体处理键值的代码如下:
uint16 ProjectApp_ProcessEvent( uint8 task_id, uint16 events )
{
......
if ( events & SYS_EVENT_MSG )
{
......
case KEY_CHANGE : ProjectApp_HandleKeys(((keyChange_t *)MSGpkt)->state,((keyChange_t *)MSGpkt)->keys);break;
......
}
......
}
具体ProjectApp_HandleKeys( )这个键值处理函数实现什么功能,就完全取决于大家自己啦~
(配套源码、软件、开发板等资源,可移步博客同名QQ群:拿破仑ZigBee)