今天下午的時候,調試努力之下,終於把紅外解碼弄出來了。其實之前有次比賽的時候就已經用到了紅外,只是那次用的是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); }
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); //發送信號量,進行碼制轉換任務,個人任務只是簡單的實現了判斷解碼是否成功。 } } }