新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > uc/OS-II下ARM7定時器捕獲實現(xiàn)紅外解碼

        uc/OS-II下ARM7定時器捕獲實現(xiàn)紅外解碼

        作者: 時間:2016-11-21 來源:網(wǎng)絡(luò) 收藏
        今天下午的時候,調(diào)試努力之下,終于把紅外解碼弄出來了。其實以前有次比賽的時候就已經(jīng)用到了紅外,只是那次用的是51單片機,用的是外部中斷和延時檢測脈寬來進行解碼,因為51的時鐘這些比較簡單,所以解碼很容易就正確了。但是現(xiàn)在換到了ARM7平臺下,由于對它的不是很熟悉,怎么用普通語句實現(xiàn)精確延時對我來說是個難點。最后考慮用兩個方案來實現(xiàn)紅外的解碼。方案一是用外部中斷加定時器延時檢測脈寬進行解碼,但是結(jié)果并沒有我想的那樣美好,調(diào)試了半天也沒有實現(xiàn)正確的解碼,個人認為是任務(wù)節(jié)拍的影響,但是確實不知道該怎么修改,最后放棄方案一,改用方案二,用定時器捕獲實現(xiàn)紅外的解碼,并最終實現(xiàn)。

        LPC2103芯片帶有定時器捕獲,可以設(shè)置為下降沿,上升沿或雙邊沿捕獲中斷。因為結(jié)合到此款紅外編碼方式,所以采用下降沿進行捕獲。定時器0因為用作了系統(tǒng)節(jié)拍定時器,所以我選擇了定時器1的捕獲。

        本文引用地址:http://www.104case.com/article/201611/319111.htm

        定時器1進行如下的初始化。

        [plain]view plaincopy
        print?
        1. voidSetTimer(void)
        2. {
        3. T1TCR=0x02;//關(guān)閉復(fù)位定時器1
        4. T1PR=10;//11分頻,約1us計時一次(外設(shè)時鐘11.0592MHZ)
        5. T1CCR=0x06;//下降沿捕獲并產(chǎn)生中斷
        6. T1IR=0x10;//清除定時器1捕獲0中斷
        7. T1TCR=0x01;//開啟定時器1
        8. VICVectAddr1=(uint32)Timer1_Handler;//中斷向量相關(guān)設(shè)置
        9. VICVectCntl1=(0x20|0x05);
        10. VICIntEnable|=(1<<5);
        11. }



        然后在定時器1中斷服務(wù)函數(shù)里,就算出相鄰兩次下降沿之間的差值。然后通過消息郵箱把消息發(fā)送到脈寬檢測任務(wù)進行處理。

        [plain]view plaincopy
        print?
        1. voidTimer1_Exception()
        2. {
        3. staticuint32tOld;//保存舊的下降沿捕獲值
        4. uint32tNew;//保存新的下降沿捕獲值
        5. statici;
        6. OS_ENTER_CRITICAL();
        7. T1IR=0x10;//清除定時器1捕獲0中斷
        8. tNew=T1CR0;
        9. tValue=tNew-tOld;//得到兩次下降沿之間的差值
        10. tOld=tNew;//以便下次中斷處理
        11. OSMboxPost(Msg,(void*)tValue);//發(fā)送消息郵箱,行為同步
        12. OS_EXIT_CRITICAL();
        13. VICVectAddr=0x00;
        14. }

        在檢測脈寬任務(wù)里,我只需要根據(jù)測定脈寬與本來編碼原有的脈寬進行比較判斷,然后進行相關(guān)移位數(shù)據(jù)操作,得到數(shù)據(jù)碼值。

        因為我的遙控器有點不同,地址碼與地址反碼不互反,所以不能進行地址的判斷,所以濾除掉了引導(dǎo)碼與地址碼,直接進行了數(shù)據(jù)碼的處理。

        只要數(shù)據(jù)碼與數(shù)據(jù)反碼取反相同,則調(diào)試LED閃爍一下。

        當(dāng)然我還沒有具體知道遙控器按鍵對應(yīng)的具體碼制是多少,而且還沒有檢測到連發(fā)碼,留待下次把碼制通過串口發(fā)送到上位機進行顯示。

        [plain]view plaincopy
        print?

        [plain]view plaincopy
        print?
        1. 這是檢測脈寬任務(wù)的核心代碼:

          while(1)
        2. {
        3. OSMboxPend(Msg,0,&err);//等待脈寬檢測消息
        4. if(tValue>2145&&tValue<2345)//進行脈寬檢測
        5. {
        6. ucTemp=1;//邏輯1
        7. }
        8. elseif(tValue>1025&&tValue<1225)
        9. {
        10. ucTemp=0;//邏輯0
        11. }
        12. elseif(tValue>13400&&tValue<13600)
        13. {
        14. ucCounter=0;//引導(dǎo)碼
        15. usData0=0;
        16. usData1=0;
        17. flag=1;
        18. }
        19. else
        20. {
        21. continue;
        22. }
        23. if(flag)//數(shù)據(jù)處理過程
        24. {
        25. ucCounter++;
        26. if(ucCounter<16)
        27. {
        28. usData0|=(uint16)ucTemp;
        29. usData0<<=1;
        30. }
        31. elseif(ucCounter==16)
        32. {
        33. usData0|=(uint16)ucTemp;
        34. }
        35. elseif(ucCounter<32)
        36. {
        37. usData1|=(uint16)ucTemp;
        38. usData1<<=1;
        39. }
        40. elseif(ucCounter==32)
        41. {
        42. usData1|=(uint16)ucTemp;
        43. flag=0;
        44. OSSemPost(Sem);//發(fā)送信號量,進行碼制轉(zhuǎn)換任務(wù),我的任務(wù)只是簡單的實現(xiàn)了判斷解碼是否成功。
        45. }
        46. }
        47. }



        評論


        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 东乌| 元阳县| 兴海县| 磐安县| 麟游县| 武强县| 轮台县| 樟树市| 钟山县| 加查县| 沙雅县| 土默特左旗| 晴隆县| 泾源县| 万年县| 清涧县| 师宗县| 石柱| 保定市| 邮箱| 宽城| 丹巴县| 东至县| 图们市| 建湖县| 绥德县| 湘潭县| 台南市| 屯门区| 河源市| 卢湾区| 靖西县| 无极县| 安阳县| 亚东县| 前郭尔| 万年县| 宣城市| 郧西县| 囊谦县| 饶阳县|