2012年6月28日 星期四

ucos-II訊息佇列處理多按鍵



上一次採用信號量的方式處理一個按鍵,採用發送和等待信號量的方式來實現該按鍵的掃描。但是如果系統有多個按鍵需要處理呢?是否還可以用信號量呢?當然其實也可以的,多個按鍵就創建對個信號量唄!這樣處理可是可以,不過很繁瑣。本文介紹另外一種處理方案:採用訊息佇列的方式。將每一個按鍵對應一條消息,當某個按鍵按下時,就發送該按鍵的消息到訊息佇列:OSQPost(KeyQEvent, Qmsg_KA);然後在按鍵處理任務重一直調用q_keymsg
= (INT8U*)OSQPend(KeyQEvent,10,&err);
讀取訊息佇列,也就是判斷該函數的返回值是否是按鍵消息Qmsg_KA,如果是則相應,如果不是則延時任務。




/*訊息佇列相關變數定義初始化-------------------------------------------------*/

OS_EVENT *KeyQEvent; /*
定義訊息佇列的事件控制塊,用於接收訊息佇列返回值,如果訊息佇列


創建成功,則返回一個指標,這個指標用於以後對訊息佇列的操作

因此,該指標可以看做是相應訊息佇列的控制碼。

QEvent = OSQCreate(&Qstart[0],10); */

INT8U err; /*
定義訊息佇列的錯誤變數 OSQPend(QEvent,2000,&err);接收消息等待錯誤*/

void *Qstart[10]; /*
定義訊息佇列的指標陣列,可容納10則消息
*/

INT8U *Qmsg_KA = "KeyA"; /*
定義一則消息,
*/

INT8U *Qmsg_KB = "KeyB"; /*
定義一則消息,*/




KeyQEvent = OSQCreate(&Qstart[0],10); /* 創建一個訊息佇列,可容納10則消息*/




void TaskKeyScan(void * pdata)/*按鍵掃描任務*/

{

INT8U KeyAState;

INT8U KeyBState;




INT8U keyA_release = 0;

INT8U keyB_release = 0;




pdata = pdata;

for(;;)

{

OSTimeDlyHMSM(0,0,0,50);




KeyAState = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13); /* 按鍵按下返回 0 */

KeyBState = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2); /*
按鍵按下返回
1 */

/*
按鍵KEYA有效
--------------------*/

if (KeyAState == 0)

{

OSTimeDlyHMSM(0,0,0,20);/*20ms
去抖動
*/

KeyAState = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13);

if (KeyAState == 0)

{

keyA_release = 1;

}

}

if (KeyAState == 1 && keyA_release == 1) /*
本次按鍵有效
*/

{

OSQPost(KeyQEvent, Qmsg_KA); /*
發送按鍵KEYA被按下消息
*/

keyA_release = 0; /*
按鍵釋放標識清除
*/

printf( "Post\n" );

}




/*按鍵KEYB有效---------------------*/

if (KeyBState == 1)

{

OSTimeDlyHMSM(0,0,0,20);

KeyBState = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2);

if (KeyBState == 1)

{

keyB_release = 1;

}

}

if (KeyBState == 0 && keyB_release == 1) /*
本次按鍵有效
*/

{

OSQPost(KeyQEvent, Qmsg_KB);/*
發送按鍵KEYB被按下消息
*/

keyB_release = 0; /*
按鍵釋放標識清除
*/

printf( "Post\n" );

}



}

}




void TaskLed(void * pdata)/* 按鍵相應任務*/

{

INT8U *q_keymsg;

pdata = pdata;



for(;;)

{

q_keymsg = (INT8U*)OSQPend(KeyQEvent,10,&err);/*
掃描訊息佇列
*/

if(err == OS_NO_ERR)

{

if(q_keymsg == Qmsg_KB)/*
如果按鍵B被按鍵,則相應相關處理函數
*/

{

LED4_TOGGLE();

Num ++;

}

else if(q_keymsg == Qmsg_KA) /*
如果按鍵A被按鍵
*/



{

LED4_TOGGLE();

Num --;

}

}

}

}




 





沒有留言:

張貼留言

FPGA Verilog 的學習經驗,提供給要入門的新手

今天簡單說說 FPGA Verilog 的學習經驗,提供給要入門的新手: 1.對自己寫的FPGA Verilog程式,所生成的數位電路要心中有數。 這一點個人認為很重要,就正如寫 C語言,心中要能生成對應的組合語言一樣,我是這樣要求自己的。 雖然 FPGA Verilog語言...