<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        51紅外解碼調試筆記

        作者:未知   來源:本站原創   點擊數:  更新時間:2014年04月27日   【字體:

        轉自:http://blog.sina.com.cn/s/blog_6b86b0f20101iq0q.html


            前陣子幫他們做實習小車的買東西,看著便宜就順便買了個紅外的遙控器和1838的紅外接收頭子。這兩天閑著沒事,看了很多資料才終于完成了紅外解碼,的確是久了沒玩51,好多東西生疏了導致調試過程幾經挫折,經過這次復習了好多51的東西,受益匪淺。

            查閱資料得知常見紅外編碼為PPM制式。紅外發射端以脈寬0.565ms、間隔0.56ms的脈沖信號表示二進制“0”,以脈寬0.565ms,間隔1.65ms的脈沖信號為“1”。如下圖.
        上述“0”、“1”組成的32位二進制碼經過38KHz的載波進行二次調制以提高發射效率、降低電源功耗。

        32位二進制碼組中,前16位為用戶識別碼,能區別不同電氣設備防止不同機種遙控碼相互干擾。后16位為8位操作碼極其反碼。遙控器在按下后周期性的發出一種32位二進制碼,周期108ms。這108ms由一個起始碼(9ms),一個結果碼(4.5ms),低8位地址碼、高8位地址碼、8位數據碼極其8位數據反碼組成。
         
        接受時使用1838通用紅外接頭

        紅外接頭將38K載波信號過濾掉,得到與發射代碼反向接受碼。

        上述是我自己整理的資料。后經示波器驗證大致是這樣的,便開始編寫程序。

        紅外解碼的關鍵就是識別“0”和“1”。以下是具體代碼,通過51單片機接受紅外信號,解碼后將8位操作碼通過串口以十六進制發送給電腦(比較粗糙,還沒來得及完善,僅供參考)

         
        #include//單片機型號STC89C52
         
        #define uchar unsigned char
        #define uint unsigned int
         
        sbit IR=P3^2;//位定義,使用P3^2口外部中斷0
         
        uint lowtime,hightime;
        uchar a[4],m,flag;
         
        bit decode();//解碼程序
        void sci();//串口初始化
         
        void main()
        {
        // delay_ms(100);
        TR0=0;
        TH0=0;
        TL0=0;
        sci();
        EA=1;
        IT0=1;//設置外部中斷0為下降沿觸發方式
        EX0=1;//開外部中斷0
        while(1)
        {
        if(flag==1) //驗證前導碼正確后才開始解碼并向串口發送數據
        {
        decode();
        for(m=0;m<1;m++)//向串口發射a[2],及8位操作碼
        {
        SBUF=a[2];
        while(!TI);
        TI=0;
        }
        while(1);
        }
        }
        }
         
        void ext0() interrupt 0
        {
        EX0=0;//進外部中斷0后立即關閉中斷0,防止二次中斷
        TR0=1;//開定時器0
        while(IR==0);//一直計數,直到IR由0跳變到1
        TR0=0;//關閉定時器0
        lowtime=256*TH0+TL0;//lowtime儲存引導碼低電平持續時間
        TH0=0;
        TL0=0;//清空定時器0寄存器值,以備下一次計數
        TR0=1;
        while(IR==1);//等待IR由1跳表到0
        TR0=0;//關閉定時器0
        hightime=256*TH0+TL0;//hightime存儲結果碼高電平持續時間
        if((lowtime>7800)&&(lowtime<8800)&&(hightime>3600)&&(hightime<4700))
        //9000us/1.085=8294,判斷區間8800-7800
        //4500us/1.085=4100,判斷區間3600-4700
        //此值為11.0592MHz晶振時的值。  
        flag=1;//符合判斷條件則將flag標志置1,否則認為是干擾信號不予解碼
        }
         
        bit decode()
        {
        uchar temp;
        uchar i,j;
        for(i=0;i<4;i++)
        {
        for(j=0;j<7;j++)
        {
        temp>>=1;
        TH0=0;
        TL0=0;
        TR0=1;
        while(IR==0);
        TR0=0;
        lowtime=256*TH0+TL0;
        TH0=0;
        TL0=0;
        TR0=1;
        while(IR==1);
        TR0=0;
        hightime=256*TH0+TL0;
        if((lowtime<370)||(lowtime>640))//低電平時間長度不合理
        return 0;
        if((hightime>420)&&(hightime<620))//高電平持續時間560us左右即位“0”
        temp&=0x7f;
        if((hightime>1300)&&(hightime<1800))//高電平持續時間1680us左右即位“1”
        temp|=0x80;
        }
        a[i]=temp;
        }
        }
         
        void sci()
        {
        SM0=0;
        SM1=1;
        REN=1;
        TMOD=0x21;//此處注意設置定時器0的方式為工作方式1
        TH1=0xfd;
        TL1=0xfd;
        TR1=1;
        ES=1;
        }

        串口顯示出的十六進制的編碼(每次單片機斷電的時候都會向電腦發送00,不知道為什么...)
         
         
        這只是初步的程序,調試過程中狀況百出。顯示串口顯示問題,SBUFS是8位寄存器,只能存儲8位二進制數據,故32位二進制需要發送四次,每次到串口為1位十六進制數據。還有定時器0的模式,之前一直沒有設置,結果郁悶了一晚上。
         
        另外,關于紅外的用途的話,有人說這東西接受距離不遠,也就幾米(有資料說在輸出段并上1uf電容可將接收距離增加至十多米,待驗證),最致命的是它是紅外線,必須要將發射端對準接收端才能接收到信號,這就是它比不上藍牙、NRF24L01等無線通信最主要的原因。不過,NRF24L01之麻煩,以我的智商估計沒有半個月是做不出來的。
        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮