|
記錄一次使用NEC協議編碼的紅外遙控信號的解碼方式。
NEC協議簡要記錄
NEC協議是紅外遙控協議的一種,由其編碼的數據幀分別由引導碼、用戶碼、用戶碼(或者是用戶碼的反碼)、數據碼(即按鍵碼)和數據碼的反碼這五部分組成,最后還有一個停止位。引導碼表示即將開始傳輸32位的二進制數據;引導碼之后的部分長度為4字節一共32位;第一字節為用戶碼;第二字節可能是用戶碼,也可能是用戶碼的反碼,具體由廠商決定;第三字節是當前按鍵的按鍵碼;第四字節是按鍵碼的反碼;停止位主要起隔離作用,一般不進行判斷,也不需要理會。每一字節的數據從低位到高位依次發送。
NEC協議編碼方式
NEC協議的每一比特數據本身也需要進行編碼,編碼后再進行載波調制。
引導碼:9ms的高電平 + 4.5ms的低電平
比特值0:0.56ms的高電平 + 0.56ms的低電平
比特值1:0.56ms的高電平 + 1.68ms的低電平
發射端和接收端的電平相反,即:
引導碼:9ms的低電平 + 4.5ms的高電平
比特值0:0.56ms的低電平 + 0.56ms的高電平
比特值1:0.56ms的低電平 + 1.68ms的高電平
源程序記錄
按下紅外遙控器的任一按鍵1~9,即可在開發板的數碼管模塊的左邊第一位上顯示對應的按鍵數字。
- #include<reg51.h>
- sbit OUTPUT=P3^2; //P3.2引腳為單片機外部中斷0的觸發引腳,同時連接紅外接收模塊IR 1838的輸出端,在模塊輸出信號的同時進入外部中斷0的服務函數
- sbit Wei=P2^7; //數碼管模塊位鎖存
- unsigned char Code[9]={0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //數碼管顯示從“1”到“9”的段碼
- unsigned char Code0[4];
- unsigned char Code1[33];
- unsigned char time;
- bit m,n; //定義兩個標志位;標志位m表示一幀數據解碼完畢,標志位n表示一幀數據接收完畢
- void ET_0() interrupt 1 using 1 //定時器0中斷
- {
- time++; //對兩個下降沿之間的時間間隔進行計數
- }
- void EX_0() interrupt 0 //外部中斷0
- {
- static unsigned char i;
- static bit START;
- if(START)
- {
- if(time<63&&time>=33) //引導碼,9ms+4.5ms
- {
- i=0;
- }
- Code1[i]=time; //存儲兩個下降沿之間的時間間隔,將用于數據幀的“0”和“1”
- time=0;
- i++;
- if(i==33)
- {
- n=1;
- i=0;
- }
- }
- else
- {
- time=0;
- START=1;
- }
- }
- void ET0_init() //定時器0中斷初始化
- {
- TMOD=0x02; //定時器0工作在方式2
- TH0=0x00; //重載值
- TL0=0x00; //初始值
- ET0=1; //開啟定時器0中斷
- TR0=1;
- }
- void EX0_init() //外部中斷0初始化
- {
- IT0=1; //設置外部中斷0為下降沿觸發
- EX0=1; //開啟外部中斷0
- EA=1; //開啟總中斷
- }
- void DECODE() //紅外解碼
- {
- unsigned char i,j,k;
- unsigned char x,y;
- k=1;
- for(i=0;i<4;i++) //對數據幀中的4個字節進行處理
- {
- for(j=1;j<=8;j++) //對一個字節中的8位進行處理
- {
- x=Code1[k];
- if(x>7) //時間間隔大于某值則為1,與晶振(12MHz)相關,允許誤差
- {
- y|=0x80;
- }
- if(j<8)
- {
- y>>=1;
- }
- k++;
- }
- Code0[i]=y;
- y=0;
- }
- m=1;
- }
- void NUMBER() //將紅外遙控器的按鍵值轉換為數碼管的段值
- {
- switch(Code0[2])
- {
- case 0x0c:P0=Code[0];break;
- case 0x18:P0=Code[1];break;
- case 0x5e:P0=Code[2];break;
- case 0x08:P0=Code[3];break;
- case 0x1c:P0=Code[4];break;
- case 0x5a:P0=Code[5];break;
- case 0x42:P0=Code[6];break;
- case 0x52:P0=Code[7];break;
- case 0x4a:P0=Code[8];break;
- default:break;
- }
- m=0;
- }
- void main()
- {
- ET0_init();
- EX0_init();
-
- P0=0xfe; //取數碼管模塊左邊第一位選通
- Wei=1;
- Wei=0;
-
- while(1)
- {
- if(n)
- {
- DECODE();
- n=0;
- }
- if(m)
- {
- NUMBER();
- }
- }
- }
復制代碼
原理圖
|
評分
-
查看全部評分
|