歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 紅外協議之NEC協議

紅外協議之NEC協議

日期:2017/2/28 14:28:16   编辑:Linux教程

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解碼出來還是有點細微差錯。查了很久,也沒有收獲。心裡有點小郁悶。今早起來,仔細地看了看他人的參考代碼。突然被下面一個小小的細節折服了。

請注意這段代碼:

void hal_NEC_decode(uchar *addr,uchar *addrt,uchar *comm,uchar *commt)
{
uchar i,j,k;
uchar tmp1=0;

while(NECFinshFlag==0);
NECFinshFlag=0;

for(i=0,k=1;i<4;i=i+1)
{
for(j=1;j<=8;j++)
{
if(NECTimerTable[k++] > 7)
{
tmp1 |=0x80;
}
tmp1 >>=1;
}
switch(i)
{
case 0:*addr=tmp1;break;
case 1:*addrt=tmp1;break;
case 2:*comm=tmp1;break;
case 3:*commt=tmp1;break;
}
tmp1=0;
}
}

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

void hal_NEC_decode(uchar *addr,uchar *addrt,uchar *comm,uchar *commt)
{
uchar i,j,k;
uchar tmp1;

while(NECFrameFlag==0);
NECFrameFlag=0;

for(i=0,k=1;i<4;i=i+1)
{
tmp1=0;
for(j=0;j<8;j++)
{
tmp1 >>=1;//事先右移一位,防止最後一次循環的出錯
if(NECTimerTable[k++] >8)
{
tmp1 |=0x80;
}
}
switch(i)
{
case 0:*addr=tmp1;break;
case 1:*addrt=tmp1;break;
case 2:*comm=tmp1;break;
case 3:*commt=tmp1;break;
}
}
}

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

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

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

Copyright © Linux教程網 All Rights Reserved