紅外線遙控是目前使用最廣泛的一種通訊和遙控手段。由於紅外線遙控裝置具有體積小、功耗低、功能強、成本低等特點,因而,繼彩電、錄影機之後,在錄音機、音響裝置、空凋機以及玩具等其它小型電器裝置上也紛紛採用紅外線遙控。工業裝置中,在高壓、輻射、有毒氣體、粉塵等環境下,採用紅外線遙控不僅完全可靠而且能有效地隔離電氣幹擾。
1 紅外遙控系統
通用紅外遙控系統由發射和接收兩大部分組成,應用編/解碼專用整合電路晶片來進行控制操作,1所示。發射部分包括鍵盤矩陣、編碼調製、LED紅外發送器;接收部分包括光、電轉換放大器、解調、解碼電路。
2 遙控發射器及其編碼
遙控發射器專用晶片很多,根據編碼格式可以分成兩大類,這裡我們以運用比較廣泛,解碼比較容易的一類來加以說明,現以日本NEC的uPD6121G組成發射電路為例說明編碼原理。當發射器按鍵按下後,即有遙控碼發出,所按的鍵不同遙控編碼也不同。這種遙控碼具有以下特徵:
採用脈寬調製的串列碼,以脈寬為0.565ms、間隔0.56ms、周期為1.125ms的組合表示二進位的“0”;以脈寬為0.565ms、間隔1.685ms、周期為2.25ms的組合表示二進位的“1”,其波形2所示。
上述“0”和“1”組成的32位二進位碼經38kHz的載頻進行二次調製以提高發射效率,達到降低電源功耗的目的。然後再通過紅外發射二極體產生紅外線向空間發射,3所示。
UPD6121G產生的遙控編碼是連續的32位二進位碼組,其中前16位為使用者識別碼,能區別不同的電器裝置,防止不同機種遙控碼互相干擾。該晶片的使用者識別碼固定為十六進位01H;後16位為8位作業碼(功能碼)及其反碼。UPD6121G最多額128種不同組合的編碼。
遙控器在按鍵按下後,周期性地發出同一種32位二進位碼,周期約為108ms。一組碼本身的期間隨它包含的二進位“0”和“1”的個數不同而不同,大約在45~63ms之間,圖4為發射波形圖。
當一個鍵按下超過36ms,振蕩器使晶片啟用,將發射一組108ms的編碼脈衝,這108ms發射代碼由一個起始碼(9ms),一個結果碼(4.5ms),低8位地址碼(9ms~18ms),高8位地址碼(9ms~18ms),8位元據碼(9ms~18ms)和這8位元據的反碼(9ms~18ms)組成。如果鍵按下超過108ms仍未鬆開,接下來發射的代碼(連發代碼)將僅由起始碼(9ms)和結束碼(2.5ms)組成。
代碼格式(以接收代碼為準,接收代碼與發射代碼反向)
①位定義
②單發代碼格式
③連發代碼格式
註:代碼寬度演算法:
16位地址碼的最短寬度:1.12×16=18ms 16位地址碼的最長寬度:2.24ms×16=36ms
易知8位元據代碼及其8位反代碼的寬度和不變:(1.12ms+2.24ms)×8=27ms
所以32位代碼的寬度為(18ms+27ms)~(36ms+27ms)
1. 解碼的關鍵是如何識別“0”和“1”,從位的定義我們可以發現“0”、“1”均以0.56ms的低電平開始,不同的是高電平的寬度不同,“0”為0.56ms,“1”為1.68ms,所以必鬚根據高電平的寬度區別“0”和“1”。如果從0.56ms低電平過後,開始延時,0.56ms以後,若讀到的電平為低,說明該位為“0”,反之則為“1”,為了可靠起見,延時必須比0.56ms長些,但又不能超過1.12ms,否則如果該位為“0”,讀到的已是下一位的高電平,因此取(1.12ms+0.56ms)/2=0.84ms最為可靠,一般取0.84ms左右均可。
2. 根據碼的格式,應該等待9ms的起始碼和4.5ms的結果碼完成後才能讀碼。
接收器及解碼
一體化紅外線接收器是一種集紅外線接收和放大於一體,不需要任何外接元件,就能完成從紅外線接收到輸出與TTL電平訊號相容的所有工作,而體積和普通的塑封三極體大小一樣,它適合於各種紅外線遙控和紅外線資料轉送。
下面是一個對51實驗板配套的紅外線遙控器的解碼程式,它可以把32鍵的紅外遙控器每一個按鍵的索引值讀出來,並且通過實驗板上P1口的8個LED顯示出來,在解碼成功的同時並且能發出“嘀嘀嘀”的提示音。
紅外遙控器軟體解碼原理及程式 紅外一開始發送一段13.5ms的引導碼,引導碼由9ms的高電平和4.5ms的低電平組成,跟著引導碼是系統碼,系統反碼,按鍵碼,按鍵反碼,如果按著鍵不放,則遙控器則發送一段重複碼,重複碼由9ms的高電平,2.25ms的低電平,跟著是一個短脈衝,本程式經過試用,能解大部分遙控器的編碼! #include "at89x52.h" #define NULL 0x00//資料無效 #define RESET 0X01//程式複位 #define REQUEST 0X02//請求訊號 #define ACK 0x03//應答訊號,在接收資料後發送ACK訊號表示資料接收正確, 也位請求訊號的應答訊號 #define NACK 0x04//應答訊號,表示接收資料錯誤 #define BUSY 0x05//忙訊號,表示正在忙 #define FREE 0x06//空閑訊號,表示處於空閑狀態 #define READ_IR 0x0b//讀取紅外 #define STORE_IR 0x0c//儲存資料 #define READ_KEY 0x0d//讀取索引值 #define RECEIVE 0Xf400//接收緩衝開始地址 #define SEND 0xfa00//發送緩衝開始地址 #define IR 0x50//紅外接收緩衝開始地址 #define HEAD 0xaa//資料幀頭 #define TAIL 0x55//資料幀尾 #define SDA P1_7 #define SCL P1_6 unsigned char xdata *buf1; //接受資料緩衝 unsigned int buf1_length; //接收到的資料實際長度 unsigned char xdata *buf2; //發送資料緩衝 unsigned int buf2_length; //要發送的資料實際長度 bit buf1_flag; //接收標誌,1表示接受到一個資料幀,0表示沒有接受到資料幀或資料幀為空白 bit buf2_flag; //發送標誌,1表示需要發送或沒發送完畢,0表示沒有要發送的資料或發送完畢 unsigned char state1,state2; //用來標誌接收字元的狀態,state1用來表示接收狀態,state2用來表示發送狀態 unsigned char data *ir; union{ unsigned char a[2]; unsigned int b; unsigned char data *p1[2]; unsigned int data *p2[2]; unsigned char xdata *p3; //紅外緩衝的指標 unsigned int xdata *p4; }p; //union{ // // unsigned char a[2]; // // unsigned int b; // unsigned char data *p1[2]; // unsigned int data *p2[2]; // unsigned char xdata *p3; // unsigned int xdata *p4; //地址指標 //}q; // union{ unsigned char a[2]; unsigned int b; }count; union{ unsigned char a[2]; unsigned int b; }temp; union{ unsigned char a[4]; unsigned int b[2]; unsigned long c; }ir_code; union{ unsigned char a[4]; unsigned int b[2]; unsigned long c; unsigned char data *p1[4]; unsigned int data *p2[4]; unsigned char xdata *p3[2]; unsigned int xdata *p4[2]; }i; unsigned char ir_key; bit ir_flag; //紅外接收標誌,0為緩衝區空,1為接收成功,2為緩衝溢出 void sub(void); void delay(void); void ie_0(void); void tf_0(void); void ie_1(void); void tf_1(void); void tf_2(void); void read_ir(void); void ir_jiema(void); void ir_init(void); void ir_exit(void); void store_ir(void); void read_key(void); void reset_iic(void); unsigned char read_byte_ack_iic(void); unsigned char read_byte_nack_iic(void); bit write_byte_iic(unsigned char a); void send_ack_iic(void); void send_nack_iic(void); bit receive_ack_iic(void); void start_iic(void); void stop_iic(void); void write_key_data(unsigned char a); unsigned int read_key_data(unsigned char a); void ie0(void) interrupt 0{ie_0();} void tf0(void) interrupt 1{tf_0();} void ie1(void) interrupt 2{ie_1();} void tf1(void) interrupt 3{tf_1();tf_2();} void tf2(void) interrupt 5{ //採用中斷方式跟查詢方式相結合的辦法解 碼 EA=0; //禁止中斷 if(TF2){ //判斷是否是溢出還是電平變化產生的中斷 TF2=0; //如果是溢出產生的中斷則清除溢出位,重 新開放中斷退出 EA=1; goto end; } EXF2=0; //清除電平變化產生的中斷位 *ir=RCAP2H; //把捕捉的數儲存起來 ir++; *ir=RCAP2L; *ir++; F0=1; TR0=1; |