10 在ZStack里的按键驱动

来源:互联网 发布:软件试用期过了 编辑:程序博客网 时间:2024/05/19 19:31

到目前我们可以通过设置任务的事件信息,从而让任务的事件处理函数触发。但除了事件外如还需要传递额外的数据(消息)给另一任务时,就需要用下面的函数功能:

OSAL/OSAL.htypedef struct{  uint8  event; //记录消息的种类,如按键消息则为KEY_CHANGE  uint8  status;} osal_event_hdr_t; //每种消息都包括此结构体作头部extern uint8 * osal_msg_allocate(uint16 len ); //动态分配消息所需的空间extern uint8 osal_msg_deallocate( uint8 *msg_ptr ); //回收消息的空间extern uint8 osal_set_event( uint8 task_id, uint16 event_flag ); //设置指定号的任务发生event_flag事件. 即tasksEvents[task_id] |= event_flag;extern uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr ); //发出消息到指定号的任务.  调用此函数时会设置指定号的任务发生SYS_EVENT_MSG.即osal_set_event( destination_task, SYS_EVENT_MSG ) extern uint8 *osal_msg_receive( uint8 task_id ); //接收指定号的任务的消息

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

在ZStack里对按键功能的封装在工程的HAL/include/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...typedef void (*halKeyCBack_t) (uint8 keys, uint8 state);extern bool Hal_KeyIntEnable;//下需的函数我们不用直接调用, 这些函数应由hal层的任务来调用。当检查有按键按下时,会设置指定任务的事件(KEY_CHANGE),并把包含按键信息的消息发送到指定的任务.extern void HalKeyInit( void );extern void HalKeyConfig( bool interruptEnable, const halKeyCBack_t cback);extern uint8 HalKeyRead( void);extern void HalKeyPoll ( void );    ...

///////////////////////////////////////////////////////////////////////////////////////
按键的初始化过程:

int main( void ){    ...    InitBoard( OB_COLD );    ...    InitBoard( OB_READY );    ...}void InitBoard( uint8 level ){    ...    HalKeyConfig(HAL_KEY_INTERRUPT_DISABLE, OnBoard_KeyCallback);    ...}void HalKeyConfig (bool interruptEnable, halKeyCBack_t cback){  Hal_KeyIntEnable = interruptEnable; //用全局变量 Hal_KeyIntEnable存放按键是否用中断功能  pHalKeyProcessFunction = cback; //用全局函数指针变量pHalKeyProcessFunction存放当按键状态发生变化时需要调用的函数的地址    ...}//////////////////////////任务需要接收按键消息的初始化RegisterForKeys(mytask_id); //指定mytask_id任务号的任务接收按键的消息uint8 RegisterForKeys( uint8 task_id ){    registeredKeysTaskID = task_id; //用全局变量registeredKeysTaskID来存放要接收按键消息的任务号     ...}/////////////////////////////按键在hal任务里的检查:uint16 Hal_ProcessEvent( uint8 task_id, uint16 events ) // hal任务的事件处理函数{    ...  if (events & HAL_KEY_EVENT)  {    HalKeyPoll(); //检查按键状态,并发出按键消息    if (!Hal_KeyIntEnable)    {      osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 100);      //定时100ms后,给hal任务设置HAL_KEY_EVENT事件。也就是用定时器每隔100ms来检查按键.    }    ...}void HalKeyPoll (void){  uint8 keys = 0;    ...  if (!Hal_KeyIntEnable)  {    if (keys == halKeySavedKeys)    {      return;    }    halKeySavedKeys = keys;  }  else  {  }    ...  if (HAL_PUSH_BUTTON1()) //检查按键是否按下   {    keys |= HAL_KEY_SW_6;  }  if (keys && (pHalKeyProcessFunction))  {    (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);    //当有键按下时,需调用OnBoard_KeyCallback函数  }}void OnBoard_KeyCallback ( uint8 keys, uint8 state ){  uint8 shift;  (void)state;    ...  if ( OnBoard_SendKeys( keys, shift ) != ZSuccess )  {  }  ...}////////////typedef struct{  osal_event_hdr_t hdr; //每种消息都包含此头部  uint8 state; // shift  uint8 keys;  // keys} keyChange_t;  //按键的消息类型uint8 OnBoard_SendKeys( uint8 keys, uint8 state ){  keyChange_t *msgPtr;  if ( registeredKeysTaskID != NO_TASK_ID )  {    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 ); //往指定的任务发出按键消息, 同时也会设置任务事件:tasksEvents[registeredKeysTaskID] |= SYS_EVENT_MSG. 接收消息的任务通过调用osal_msg_receive函数就可以得到msgPtr数据了    }    return ( ZSuccess );    ...}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
因现用的开发板与TI原厂的开发板不同,所以又得修改下里面的代码了.

这里写图片描述

修改:

#define PUSH1_POLARITY    ACTIVE_LOW#define PUSH2_POLARITY    ACTIVE_LOWvoid HalKeyPoll (void){  uint8 keys = 0;  if (HAL_PUSH_BUTTON1())  {    keys |= HAL_KEY_SW_1;  }  if (HAL_PUSH_BUTTON2())  {    keys |= HAL_KEY_SW_2;  }    if (!Hal_KeyIntEnable)  {    if (keys == halKeySavedKeys)      return;    halKeySavedKeys = keys;  }  else  {  }  if (keys && (pHalKeyProcessFunction))  {    (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);  }}

///////////////////////////
用两个按键分别控制一个led灯的亮灭
MyApp.c

#include "OnBoard.h"#include "MyApp.h"#include "hal_led.h"#include "hal_key.h"#define TIME_OUT_EVENT 0x4#define TIME_LEN       2000uint8  mytask_id; //用于存放本身的任务号void MyApp_Init(uint8 task_id ){   mytask_id = task_id;    HalLedSet(HAL_LED_ALL, HAL_LED_MODE_OFF);   RegisterForKeys(mytask_id); //设置当前任务接收按键消息}uint16 MyApp_ProcessEvent(uint8 task_id, uint16 events ){  keyChange_t *key_evt;  if ( events & SYS_EVENT_MSG ) //当有按键消息时,任务的事件会是SYS_EVENT_MSG  {    key_evt = (keyChange_t *)osal_msg_receive(mytask_id);    if (key_evt->hdr.event == KEY_CHANGE)    {                        if (key_evt->keys  &  HAL_KEY_SW_1)            HalLedSet(HAL_LED_1, HAL_LED_MODE_TOGGLE);        if (key_evt->keys  &  HAL_KEY_SW_2)            HalLedSet(HAL_LED_2, HAL_LED_MODE_TOGGLE);      }     osal_msg_deallocate( (uint8 *)key_evt ); //回收消息的空间  }      if (events & TIME_OUT_EVENT) //定时器的事件  {     ;  }  return 0;}
原创粉丝点击