原创 原代码实例:驱动器 in ZRTOS(2)

2008-9-13 00:33 2610 3 3 分类: 汽车电子

嵌入式产品中有许多面板式按键(Adhesive Keypad),下面的原代码演示如何在ZRTOS中使用驱动器来实现面板式按键。
1697181c-2e27-4184-8d1f-cd8d812df1b5.JPG 


1、问题综述
在本例中有5个按键,它们分别是MENU,UP,DOWN,SELECT, and PRINT. 键的输入信号被分别被引入到A/D入口,当键未被按下时,入口为高电位,一但键被按下,入口转为低电位。以下是部分原代码:


#define _KEY_ALL_RELEASED        (0)
#define _KEY_MENU                (1)
#define _KEY_PRINT               (2)
#define _KEY_SELECT              (3)
#define _KEY_DOWN                (4)
#define _KEY_UP                  (5)


#define _KEY_BD_CHECK_INTERVAL     (20) //refuse to take the same key press
                                        //within 20 tick or 200ms
#define _KEY_BD_TIME_2_LIVE    ((U8) 250)//if a menu item was not selected in 250
                                         //tick or 2500ms, the action will be
                                         //canceled
 
static U8 time_out; //time out timer
static U8 key_status; //key status, either pressed or release
static long timer = _KEY_BD_CHECK_INTERVAL*3;      //time out timer


void key_bd_Init(void) //keypad initialization
{
  //...
  rtos_taskSpawn(RTOS_PEND_FOREVER_PRI-4, (RTOS_FUNCPTR) key_bd_task, 0); //
  //spawn a task to handle keypad input


  timer = _KEY_BD_SELECTED_INTERVAL;
  sem = rtos_semBCreate(0, SEM_EMPTY); //create a semaphone to inform the task
                                       //key_bd_task


  //...


  key_status = _KEY_ALL_RELEASED;
}


//
static int get_key_bd_data(U16 fd, U8 key) //get input from keypad
{                        //fd - file descriptor of device driver of a key
                         //key - the key to be detected
  U16 data[2];//data to read;
  if (read(open(fd), (char*) data, 2) > 0) { //read data from fd
    //the data is available
    if (data[0]) { //the key is pressed
      if (key_status == _KEY_ALL_RELEASED) { //the key is freshly pressed
        time_out = _KEY_BD_TIME_2_LIVE; //set a time out time
        key_status = key; //set the key status to "this key was pressed"
        return TRUE; //return action flag
      }
    } else { //data is released
      if (key == key_status) { //this key used to be pressed, now released
        key_status = _KEY_ALL_RELEASED;//set the key status as released
      }
    }
    return 0;//return action flag
  }
  return ERROR; //there is no data in this device driver
}


//
static void key_bd_task(void) //periodic task with a priod of "timer"
                              //the task to handle keypad press
{
  int delta;
  long result = rtos_semTake(sem, timer);//try to get the semaphone with a timeout
  if (result == (long) OK) return; //this is not a time out, do nothing


  //it is a time out
  //...
 
  timer = _KEY_BD_CHECK_INTERVAL;//reset the timeout timer
 
  if (time_out != (U8) 255 && time_out) {
    time_out--; //decremental the time out timer, as a menu item was not selected
                //if time_out == 0, the action will be canceled
  }
  
  delta = get_key_bd_data(SOS_INPUT_BUTTON, _KEY_MENU); //check key "MENU"
  if (delta > 0) { //"MENU" key is pressed
      //...
  } else if (delta < 0) goto _out; //the device driver not ready, why ? think about
 
  if (get_key_bd_data(PRNT_INPUT_BUTTON, _KEY_PRINT)) {//check key "PRINT"
    //the key "PRINT" pressed
    //...
  } else
    
  if (get_key_bd_data(SLCT_INPUT_BUTTON, _KEY_SELECT)) {//check key "SELECT"
    //the key "SELECT" pressed
    //...
  } else


  if (get_key_bd_data(DNW_INPUT_BUTTON, _KEY_DOWN)) {//check key "DOWN"
    //the key "DOWN" pressed
    //...
  } else


  if (get_key_bd_data(UP_INPUT_BUTTON, _KEY_UP)) { //check key "UP"
   //the key "UP" pressed
   //...
  }
 
 _out: 
  if (time_out == 0) {
    init_kd(); //cancel the action
  }
}


2、结论
在上述代码中,任务的周期由时钟“timer”确定。设计者即可以用rtos_taskDelay()也可以用rtos_semTake()来实现。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条