首先,當然要給按鍵掃描創建一個任務: OSTaskCreate(TaskKeyScan, (void * )0,
(OS_STK *)&TASK_KEY_STK[KEY_STK_SIZE-1], 23);
其次,創建一個信號量,賦值為0表示一個或者多個事件的發生,在這裡表示按鍵按下這個事件:SemEvent = OSSemCreate(0);
然後,就是按鍵任務的代碼,如下:
void TaskKeyScan(void * pdata)
{
INT8U KeyAState; /* 讀取按鍵值 */
INT8U key_press = 0;
pdata = pdata;
for(;;)
{
OSTimeDlyHMSM(0,0,0,20); /* 每隔20ms掃描一次按鍵 */
KeyAState = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2); /* 按鍵按下返回 1 */
if (KeyAState == 1)
{
OSTimeDlyHMSM(0,0,0,20); /* 20ms去抖動 */
KeyAState = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2);
if (KeyAState == 1)
{
key_press = 1; /* 按鍵確認標識置位元 */
}
}
if (KeyAState == 0 && key_release == 1) /* 本次按鍵有效 */
{
OSSemPost(SemEvent); /* 發送信號量 */
key_press = 0; /* 清除按鍵確認標識 */
printf( "Post\n" );
}
}
}
最後,在另外的任務中回應按鍵,執行按鍵操作(使LED燈翻轉):
void TaskLed(void * pdata)
{
pdata = pdata;
for(;;)
{
OSSemPend(SemEvent,10,&err); /* 掛起任務,等待信號量到來。設置100ms超時 ,如果超時則執行任務其他代碼 */
if(err == OS_NO_ERR)
{
LED_TOGGLE();
}
/*----other code----*/
}
}
以上是在作業系統中對單純的一次按鍵操作的處理代碼。類似於裸機上的查詢處理,但相比於裸機上的查詢又更有優勢之處,在等待按鍵釋放動作處理上顯示其節省CPU資源的獨特之處。另外,在嵌入式系統中,按鍵的處理不單純的限制於這種一次按鍵操作,另外還有三類:1、按鍵的短擊與連擊(音樂播放的下一曲與快進);2、按鍵的短擊與長擊(手機應用程式的退出與手機的關機);3、按鍵的按一下與按兩下。這三類按鍵動作在嵌入式設備中尤為常見,實現了少按鍵多功能,節省了有限資源。對於程式設計來說,嵌入式系統給我們的多工程式設計思想,又使得對於這類的按鍵處理也顯得較為容易,多數採用狀態機(SM)的思想,至於如何在程式中實際實現,這裡就不再討論,本文主要核心是說明如何使用信號量來簡單處理按鍵的動作以及回應。
沒有留言:
張貼留言