開發環境是keil4.70a 數組
實驗板爲神舟三號 STM32F103ZET6 post
軟件上使用到了固件庫了ucosii 學習
純粹爲了學習,分享一下學習心得 優化
首先上隊列初始化的代碼 編碼
OS_EVENT* KEY_Q; //按鍵記錄的OS隊列 void *key_list[80]; //隊列定義時要求定義指針數組 /* 推薦在main中或者main.c相似的文件和位置建立這兩個變量 */ KEY_Q = OSQCreate(key_list,80); /* 推薦在OSInit以後立馬建立這個隊列 */ //對了別忘了配置 //這些OS的功能使能 #define OS_Q_EN 1 /* Enable (1) or Disable (0) code generation for QUEUES */ #define OS_Q_ACCEPT_EN 1 /* Include code for OSQAccept() */ #define OS_Q_DEL_EN 1 /* Include code for OSQDel() */ #define OS_Q_FLUSH_EN 1 /* Include code for OSQFlush() */ #define OS_Q_PEND_ABORT_EN 1 /* Include code for OSQPendAbort() */ #define OS_Q_POST_EN 1 /* Include code for OSQPost() */ #define OS_Q_POST_FRONT_EN 1 /* Include code for OSQPostFront() */ #define OS_Q_POST_OPT_EN 1 /* Include code for OSQPostOpt() */ #define OS_Q_QUERY_EN 1 /* Include code for OSQQuery() */ //以上的文件默認在os_cfg.h中
接下來貼上的按鍵掃描的任務 .net
void key_task(void *p_arg) //該任務只實現按鍵的跟蹤功能 //高四位是上一個狀態,低四位是當前狀態 { u32 bsp_key_scaned; //每四位記錄一個狀態,一共能夠記錄8個狀態 //在後續優化中能夠考慮改爲結構體 分出8位或者16位記錄按鍵時長 u8 key_rem1 = 0x00; //第一次緩衝 //用於消抖 u8 key_rem2 = 0x00; //第二次緩衝 //用於判斷按鍵狀態是否改變 u8 key_t = 0x00; //第一次記錄 bsp_key_scaned = 0x00000000; //清空按鍵狀態 32位的數字 while(1) { OSTimeDlyHMSM(0,0,0,10); //短暫的消抖 if(!(GPIO_ReadInputDataBit(GPIO_KEY1_PORT, GPIO_KEY1))){ key_t = key_t | 0x01;} if(!(GPIO_ReadInputDataBit(GPIO_KEY2_PORT, GPIO_KEY2))){ key_t = key_t | 0x02;} // if(!(GPIO_ReadInputDataBit(GPIO_KEY3_PORT, GPIO_KEY3))){ // key_t = key_t | 0x04;} //這個按鍵在神舟三號開發板上不怎麼好用 if(!(GPIO_ReadInputDataBit(GPIO_KEY4_PORT, GPIO_KEY4))){ key_t = key_t | 0x08;} //這裏看起來挺繁瑣的,因此 擠擠←_← //以上實現掃描後一個簡單的編碼 if((key_rem1 == key_t)&&(key_rem1 != key_rem2)) //沒有抖動,而且按鍵狀態發生了改變,則Qpost { key_rem2 = key_rem1; //記錄即將post的變量,用於下一次判斷 bsp_key_scaned = ((bsp_key_scaned<<4)&0xfffffff0)|(key_t&0x0f); //傳遞參數 //注意是位操做 OSQPost(KEY_Q,(void*)bsp_key_scaned); //發送隊列內容 } key_rem1 = key_t; //記錄一個狀態 key_t = 0x00; //下一次記錄,判斷是否抖動 } }最後一個是隊列中內容的提取 也作成了一個任務
void key_solve_task(void *p_arg) { u32 key_value; //獲取實際數據 void* pKEY_Q; //獲取隊列中的指針 while(1) { OSTimeDlyHMSM(0,0,1,0); //延時 1m處理一次 pKEY_Q = OSQPend(KEY_Q,0,&err); //不過時,一直請求Q if(pKEY_Q == (void*)0) //若是返回數據爲空 { switch(err) //目前沒有加入錯誤處理 { case OS_ERR_NONE: break; default:continue;//break; //若是不是OS_NO_ERR則繼續等待1秒 } } else { key_value = (int)pKEY_Q; key_value = key_value &0x000000ff; if(GPIO_ReadOutputDataBit(GPIOF,GPIO_Pin_7) == 1){ //翻轉LED2 //表示獲得數據 GPIO_ResetBits(GPIOF,GPIO_Pin_7); } else { GPIO_SetBits(GPIOF,GPIO_Pin_7); } if(key_value == 0x00000013) //說明是先按下第一個鍵,再按下第二個鍵 { if(GPIO_ReadOutputDataBit(GPIOF,GPIO_Pin_9) == 1) { //翻轉LED4 GPIO_ResetBits(GPIOF,GPIO_Pin_9); } else { GPIO_SetBits(GPIOF,GPIO_Pin_9); } } /*else if(key_value == 0x00000057) //按鍵有問題,第三個按鍵不加入掃描 { if(GPIO_ReadOutputDataBit(GPIOF,GPIO_Pin_9)==1) {//LED按鍵有問題ADC1 第三個按鍵默認常常是按下的狀態 GPIO_ResetBits(GPIOF,GPIO_Pin_9); } else { GPIO_SetBits(GPIOF,GPIO_Pin_9); } } */ } } }我應用的時候 優先級按鍵掃描任務給得比按鍵處理要高,親測連續按下不少次以後LED2會每過1秒閃爍一下,若是知足要求LED4也會閃爍