uc/OS-II下ARM7定時器捕獲實現紅外解碼


今天下午的時候,調試努力之下,終於把紅外解碼弄出來了。微笑其實之前有次比賽的時候就已經用到了紅外,只是那次用的是51單片機,用的是外部中斷和延時檢測脈寬來進行解碼,由於51的時鐘這些比較簡單,因此解碼很容易就正確了。可是如今換到了ARM7平臺下,因爲對它的不是很熟悉,怎麼用普通語句實現精確延時對我來講是個難點。最後考慮用兩個方案來實現紅外的解碼。方案一是用外部中斷加定時器延時檢測脈寬進行解碼,可是結果並無我想的那樣美好,調試了半天也沒有實現正確的解碼,我的認爲是任務節拍的影響,可是確實不知道該怎麼修改,最後放棄方案一,改用方案二,用定時器捕獲實現紅外的解碼,並最終實現。函數

LPC2103芯片帶有定時器捕獲,能夠設置爲降低沿,上升沿或雙邊沿捕獲中斷。由於結合到此款紅外編碼方式,因此採用降低沿進行捕獲。定時器0由於用做了系統節拍定時器,因此我選擇了定時器1的捕獲。ui

定時器1進行以下的初始化。編碼

void SetTimer(void)
{
	T1TCR = 0x02;						//關閉復位定時器1
	T1PR = 10;						//11分頻,約1us計時一次(外設時鐘11.0592MHZ)
	T1CCR = 0x06;						//降低沿捕獲併產生中斷
	T1IR = 0x10;						//清除定時器1捕獲0中斷
	T1TCR = 0x01;						//開啓定時器1
	
	VICVectAddr1 = (uint32)Timer1_Handler;			//中斷向量相關設置
   	VICVectCntl1 = (0x20 | 0x05);
	VICIntEnable |= (1 << 5);
}



而後在定時器1中斷服務函數裏,就算出相鄰兩次降低沿之間的差值。而後經過消息郵箱把消息發送到脈寬檢測任務進行處理。


void Timer1_Exception()
{
	static uint32 tOld; 		//保存舊的降低沿捕獲值
	uint32 tNew;			//保存新的降低沿捕獲值
	static i;
	
	OS_ENTER_CRITICAL();
	T1IR = 0x10;			//清除定時器1捕獲0中斷
	
	tNew = T1CR0;			
	tValue = tNew - tOld;		//獲得兩次降低沿之間的差值
	tOld = tNew; 			//以便下次中斷處理
	OSMboxPost(Msg,(void*)tValue); 	//發送消息郵箱,行爲同步
	OS_EXIT_CRITICAL();
	VICVectAddr = 0x00;
}


在檢測脈寬任務裏,我只須要根據測定脈寬與原本編碼原有的脈寬進行比較判斷,而後進行相關移位數據操做,獲得數據碼值。spa

由於個人遙控器有點不一樣,地址碼與地址反碼不互反,因此不能進行地址的判斷,因此濾除掉了引導碼與地址碼,直接進行了數據碼的處理。調試

只要數據碼與數據反碼取反相同,則調試LED閃爍一下。code

固然我尚未具體知道遙控器按鍵對應的具體碼制是多少,並且尚未檢測到連發碼,留待下次把碼制經過串口發送到上位機進行顯示。同步


 

這是檢測脈寬任務的核心代碼:it

	while (1)
	{
		OSMboxPend(Msg, 0, &err);			//等待脈寬檢測消息

		if(tValue>2145  && tValue<2345)			//進行脈寬檢測
		{	
			ucTemp = 1;				//邏輯1	
		}
		
		else if(tValue>1025 && tValue<1225)
		{
			ucTemp = 0;				//邏輯0
		}
		
		else if(tValue>13400  && tValue<13600)
		{
			ucCounter = 0;				//引導碼
			usData0 = 0;
			usData1	= 0;
			flag = 1;
		}
		else
		{
			continue;
		}
		if(flag)					//數據處理過程
		{
			ucCounter++;
			if(ucCounter<16)
			{
				usData0 |= (uint16)ucTemp;
				usData0 <<= 1;
			}
			else if(ucCounter == 16)
			{
				usData0 |= (uint16)ucTemp;
			}
			else if(ucCounter < 32)
			{
				usData1 |= (uint16)ucTemp;
				usData1 <<= 1;
			}
			else if(ucCounter == 32)
			{
				usData1 |= (uint16)ucTemp;
				flag = 0;
				OSSemPost(Sem);			//發送信號量,進行碼制轉換任務,個人任務只是簡單的實現了判斷解碼是否成功。
			}
		}
	}
相關文章
相關標籤/搜索