• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統 > 設計應用 > uc/OS-II下ARM7定時器捕獲實現紅外解碼

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

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

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

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

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

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



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

    [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);//發送消息郵箱,行為同步
    12. OS_EXIT_CRITICAL();
    13. VICVectAddr=0x00;
    14. }

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

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

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

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

    [plain]view plaincopy
    print?

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

      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;//引導碼
    15. usData0=0;
    16. usData1=0;
    17. flag=1;
    18. }
    19. else
    20. {
    21. continue;
    22. }
    23. if(flag)//數據處理過程
    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);//發送信號量,進行碼制轉換任務,我的任務只是簡單的實現了判斷解碼是否成功。
    45. }
    46. }
    47. }



    評論


    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 中江县| 探索| 高要市| 雷山县| 滨州市| 通榆县| 岚皋县| 沁水县| 灵山县| 东兴市| 平顶山市| 鸡西市| 即墨市| 睢宁县| 饶阳县| 武胜县| 灵璧县| 绵竹市| 交口县| 菏泽市| 武宁县| 湾仔区| 容城县| 临清市| 华安县| 普陀区| 湖州市| 大同县| 南溪县| 周口市| 龙口市| 迭部县| 长宁区| 宣恩县| 山阳县| 乌兰察布市| 称多县| 多伦县| 阿荣旗| 多伦县| 衢州市|