NO IMAGE

紅外協議之NEC協議

NEC協議載波:38khz

其邏輯1與邏輯0的表示如圖所示:

邏輯1為2.25ms,脈衝時間560us;邏輯0為1.12ms,脈衝時間560us。所以我們根據脈衝時間長短來解碼。推薦載波佔空比為1/3至1/4。

NEC協議格式:

首次傳送的是9ms的高電平脈衝,其後是4.5ms的低電平,接下來就是8bit的地址碼(從低有效位開始發),而後是8bit的地址碼的反碼(主要是用於校驗是否出錯)。然後是8bit 的命令碼(也是從低有效位開始發),而後也是8bit 的命令碼的反碼。

  以上是一個正常的序列,但可能存在一種情況:你一直按著1個鍵,這樣的話傳送的是以110ms為週期的重複碼,如下圖:

就是說,發了一次命令碼之後,不會再傳送命令碼,而是每隔110ms時間,傳送一段重複碼。

重複碼由9ms高電平和2.25ms的低電平以及560us的高電平組成。

需要注意的是:1838紅外一體接收頭為了提高接受靈敏度。輸入高電平,其輸出的是相反的低電平。

 

  搞了一個下午和晚上,NEC解碼出來還是有點細微差錯。查了很久,也沒有收穫。心裡有點小鬱悶。今早起來,仔細地看了看他人的參考程式碼。突然被下面一個小小的細節折服了。

請注意這段程式碼:

複製程式碼
 1 void hal_NEC_decode(uchar *addr,uchar *addrt,uchar *comm,uchar *commt)
2 {
3     uchar i,j,k;
4     uchar tmp1=0;
5 
6     while(NECFinshFlag==0);
7     NECFinshFlag=0;
8 
9     for(i=0,k=1;i<4;i=i 1)
10     {
11         for(j=1;j<=8;j  )
12         {
13             if(NECTimerTable[k  ] > 7)
14             {
15                 tmp1 |=0x80;
16             }
17             tmp1 >>=1;
18         }
19         switch(i)
20         {
21             case 0:*addr=tmp1;break;
22             case 1:*addrt=tmp1;break;
23             case 2:*comm=tmp1;break;
24             case 3:*commt=tmp1;break;
25         }
26         tmp1=0;
27     }
28 }
複製程式碼

最後tmp1的值是被右移了1位。所以改為下程式碼

複製程式碼
 1 void hal_NEC_decode(uchar *addr,uchar *addrt,uchar *comm,uchar *commt)
2 {
3     uchar i,j,k;
4     uchar tmp1;
5 
6     while(NECFrameFlag==0);
7     NECFrameFlag=0;
8 
9     for(i=0,k=1;i<4;i=i 1)
10     {    
11         tmp1=0;
12         for(j=0;j<8;j  )
13         {    
14             tmp1 >>=1;//事先右移一位,防止最後一次迴圈的出錯
15             if(NECTimerTable[k  ] >8)
16             {
17                 tmp1 |=0x80;
18             }    
19         }
20         switch(i)
21         {
22             case 0:*addr=tmp1;break;
23             case 1:*addrt=tmp1;break;
24             case 2:*comm=tmp1;break;
25             case 3:*commt=tmp1;break;
26         }        
27     }
28 }
複製程式碼

  僅僅修改了這麼一個程式碼順序,程式就能比較完美的解析NEC協議來了。可見寫程式,小小的細節也是非常重要,可能會牽扯到整個的成功。

  總結:以後編寫按1bit(不管是從LSB還是MSB開始)接收組成一個位元組的程式,要格外的注意迴圈左移或者右移的情況。實現將臨時變數移動一下,免得最後1位還需要移動而造成的錯誤。

  最後附上NEC協議的命令碼(市面上常見的遙控板)