一個遙控解碼程式說明實際NEC碼過程

來源:互聯網
上載者:User

 #define WD_END           (5u+1u)  //    5ms
 #define RM_OFTM          60u   //   20ms
 #define RM_OFTM_R     100u  //   100ms
  /*以下的時序值都經過特殊處理*/
 #define RC_HEADER0           (13300000ul/RC_CLK) //13.3MS
 #define RC_HEADER1           (13700000ul/RC_CLK) //13.7MS
 #define RC_REPEAT0            (11050000ul/RC_CLK) //11.05MS
 #define RC_REPEAT1            (11450000ul/RC_CLK) //11.45MS

 #define RC_CODE1                (2250000ul/RC_CLK) //2.25MS 
 #define RC_CODE1_GOSA   ( 200000ul/RC_CLK) //0.2MS
 #define RC_CODE0                (1125000ul/RC_CLK) //1.125MS 
 #define RC_CODE0_GOSA    ( 100000ul/RC_CLK) //0.1MS 
 #define RC_CODE_0_1        (2000000ul/RC_CLK) //2 MS 
         對以上定義補充說明:程式中RC_CLK是 1185ul,這是因為分頻運算後1/27M×32=1.185(周期乘以MCU位元,注意單位跟M對應的是US)。這是表示一個CLK是對應1.185微秒,由於遙控計時器是對RCLK進行計數,所以要有一個轉換,M×RCLK(對應的時間)=13.3MS,即M=13.3M/RCLK=13.3×1000US/1.185US得對應的參考值。
 /*定義解碼所需的標誌*/
 static U32 InputData;                            //轉儲資料
 static U8 rcv_header = WRONG;        //解出頭碼標誌
 static U8 rcv_repeat = WRONG;        //解出重發標誌
static U8 BitCount;                                //位計數器
static U8 RcOffTimer;                          //遙控發碼的剩餘時間
 U8 OneCodeTime; 

void remocon_initial (void)  
{
 /*初始化IR相應的寄存器*/
        BitCount = 0; 
}
#pragma  INTERRUPT remocon_edge         //邊沿中斷觸發函數,由電平跳變即執行
void remocon_edge (void)
{
 /*在IR寄存器檢測正常的情況下,繼續執行*/
         U16 pls_cnt   = IR_MFTCMPRLD;
         if( (RC_HEADER0 <= pls_cnt) && (pls_cnt <= RC_HEADER1) )
         { 

                   //Header Pulse,判斷頭脈衝,由於反向後IR PIN預設是高電平,該寄存器主要用來
                   rcv_header = TRUE;            //獲得一次由低到高的跳變時間,NEC預設是13.5MS,13.3<13.7
                  //由於接下來就是資料碼,所以不需要時延RcOffTimer。
         }
         Else if( (RC_REPEAT0 <= pls_cnt) && (pls_cnt <= RC_REPEAT1) )
         { 

                 //Repeat Pulse,同理用來檢測重發碼,NEC標準為11.5MS,必須處於RC_REPEAT0
                 rcv_repeat = TRUE;           //與RC_REPEAT1之間,即視為識別
                 RcOffTimer = RM_OFTM_R;         //由於重發後相鄰的一次脈衝在100MS之後,所以有//必要延時,避免重複資料偵測。
          }
          Else if( rcv_header == TRUE ) //頭碼判斷出來之後
          {
                 if( BitCount < 32 )           //位長32位是標準,如果未到,繼續檢測完。
                 {
                          if((pls_cnt>=(RC_CODE0-RC_CODE0_GOSA))&&((RC_CODE1+RC_CODE1_GOSA) >= pls_cnt)) 

                          {
                                    InputData >>= 1;            //需處理新的一位,將以前的資料右移,注意發送順序//和預存程序是反向的。
                                    if ( pls_cnt >= RC_CODE_0_1 )             //如果時延大於2MS,足可以判定該次接//收的是1
                                    {
                                             InputData |= 0x80000000;//將最高接收位置1,說明該次讀出的是1
                                    }
                                    BitCount++;             //位計數器加1     
                                    RcOffTimer = RM_OFTM;             // RcOffTimer的作用很奇特,其實在每解出一//個位後,該值被重設。當解出最後一個BIT後,該值才不再改變,被後//面的                                //1MS處理函數處理消耗完剩下的時間,再集中判斷處理。該值不一//定很准,因為跟之前的01數目有關係,所以只能提供大概值。
                          }
                 }
                 OneCodeTime = WD_END; //一次解碼過程完成,做個標記值,供後面消耗時間再//判斷    
         }
}
 Void remocon_1ms (void)               //該函數處在一個1MS的控制台中,迴圈執行。其中的兩個子///////過程一個用來處理單發,一個處理重發。
{
         if( OneCodeTime != 0 ) //在一次所有的碼發完之後,OneCodeTime值固定下來,
         {          
                  OneCodeTime- -; //延遲穩定6MS之後開始解資料
                  if( OneCodeTime == 0 )
                  {
                          if( BitCount >= 32 ) //在完整接收和正確發碼的情況下,最後一次邊沿觸發//完後,BitCount是32,當然有多32位的情況下,會忽略掉後面的(偶爾)
                          { 
                                  RcOffTimer = RM_OFTM; //進入該判斷,表示正確接收開始解碼,其後// RcOffTimer是為了消耗掉一次發碼後剩餘的時間
                                  if( (InputData & 0x0000FFFFu) == CUSTOMER_CODE )//如果客戶碼是//匹配的,注意順序我們從示波器上讀的值是從右往左存,所以客戶碼轉//成16進位時從高位往低位組合。
                                  {    
                                           if( (U8)((((InputData & 0xFF000000) ^ ((InputData & 0x00FF0000u) << 8)) >> 24) ) == 0xFF ) //如果資料碼和資料碼的反碼相匹配,滿足異或為1
                                           {
                                                    RcData = (U16)((InputData & 0x00FF0000u) >> 16); //真正////解出了一個碼值 
                                                    InputData = 0; //清空轉儲變數
                                           }
                                  }
                        } 
                        BitCount  = 0;   //不管有沒有正確解出資料,在一次完整的發出資料後,要//清空BitCount和rcv_header,表示當前該次解碼結束,如果<32,無效忽略,//是一種容錯機制
                        rcv_header = WRONG;
                }

                if( RcOffTimer != 0 ) //用於消耗掉剩餘時間
                {
                        RcOffTimer--; 
                        if( RcOffTimer == 0 )
                        {
                                if( rcv_repeat == TRUE ) //如果在耗時這段時間內(顯然比重發間隔要//長),重發鍵仍然按著,RcData仍然有效。
                                {
                                        rcv_repeat = WRONG; //rcv_repeat清空,判斷下一個重發耗時間隔//是否有效
                                        RcOffTimer = RM_OFTM_R;
                                }
                                Else  //如果時間耗完後,rcv_repeat仍然0,說明沒有連按,清RcData
                                {
                                         RcData   = NP; 
                                }
                        }
              }
}//此處有誤
         需要注意的是,NEC的大體過程是上面,但在時延上(不一定是那些時間表示01),資料位元個數上(不一定是32位)。需要作些特殊處理。If•••else•••和if •••else if•••的差別,一般情況下兩者是可以通用的,但後者有個缺點是沒有出口,一旦出現兩個都不符合的值出現,將沒有任何子程式段處理,在編譯時間會警告某些後面用到的參數在子程式段中沒有初始化。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.