STM32 按鍵掃描的方式實現,用隊列傳遞參數

開發環境是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也會閃爍

原文地址http://my.oschina.net/mummy108/blog/126476 指針

相關文章
相關標籤/搜索