概述
本章介紹紅外遙控通信試驗,通過本章的學習掌握紅外遙控器的編碼原理以及使用。在 RY-51 單片機開發板上,配備了一個紅外信號接收頭,用于接收紅外信號,與開發板配套了一個紅外遙控器,用于發送紅外數據。
14.1 紅外遙控原理簡介
紅外遙控是一種無線、非接觸式數據傳輸技術、具有成本低、抗干擾能力強的短距離通信技術、被廣泛的應用于電子設備遙控通信中,包括電視、空調、手機等多種電子設備中,具有廣泛的應用前景。
紅外通信原理為將信息加載到紅外光波中,利用發射裝置發射出去,接收設備接收到紅外光后將信息解碼并做出相應的操作,便完成了一次紅外光通信。我們以一個生活中常見的例子為例,當兩個在黑暗中的人,一人拿著手電筒通過不停的開關閃爍手電筒將信息傳遞給對方。而我們這里使用的是紅外光,它的優點為紅外光不可見,對周圍環境影響較小,另外由于紅外光波長遠小于其它常用無線電波長,因此,對其它無線通信電子設備無影響。怎樣將信息加載到紅外光上呢?這就是我們常說的紅外遙控編碼協議了,目前常用的有 Philips RC-5Protocol、Sharp 協議、NEC 協議等。我們這例重點講解 NEC 協議。
在數字通信中最小的信息單位為位,即為“0”或“1”,那么在紅外通信協議中是怎么表示邏輯“0”和“1”的呢?該協議中以發射紅外載波的占空比代表信息“0”和“1”。邏輯“0”的表示法為:560us 的連續載波 +560us 的低電平,總時長為 1.125ms。邏輯“1”的表示法為:560us 的連續載波 +1680us 的低電平,總時長為 2.25ms。其中載波為 38KHz 的方波,邏輯“0”和邏輯“1”表示法如下圖所示:
圖 14-1 NEC 協議邏輯“0”和邏輯“1”表示法
傳輸一幀 NEC 格式的數據包括以下內容:
1) 同步碼頭:9ms 載波 +4.5ms 低電平;
2. 用戶碼:用戶自定義的 8bit 數據;
3. 用戶反碼:8bit 用戶碼按位取反;
4. 數據碼:8bit 數據,也稱為 8 位按鍵數據碼;
5. 數據反碼:8bit 數據碼按位取反。
由上面內容可知,實際傳輸的數據內容為用戶碼和數據碼,上面的反碼用于數據校驗,確保數據傳輸的可靠性,數據按低位到高位的順序一次傳輸。傳輸一幀 NEC 數據格式如下圖所示:
上圖為 NEC 發送模塊通過紅外光發送的數據,當接收模塊接收到 38KHz 的載波時輸出低電平,其它情況輸出高電平,因此,單片機通過測量接收到的電平高低持續時間便可解碼數據了。例如當單片機接收到 9ms 低電平 +4.5ms 高電平時,即接收到了引導碼,當接收到 560us 低電平 +560us 高電平表示接收到了數據“0”,當接收到 560us 低電平 +1680us 高電平表示接收到了數據“1”,依照上述模式便可完成一幀數據的接收。
14.2 紅外接收硬件電路設計
RY-51 單片機開發板載了紅外信號接收模塊 VS1838B,模塊外形圖下圖左邊所示,電路連接圖如下圖右邊所示。其中,輸出引腳與單片機的 P3.2 引腳相連接,同時該引腳為單片機的外部中斷 0 輸入引腳。因此,可以利用單片機的外部中斷 0 來處理紅外數據接收。
14.3 紅外解碼試驗
紅外解碼軟件編寫步驟如下:首先進行初始化將外部中斷 0 設置為下降沿觸發,當接收到的紅外信號由高電平變為低電平時,表明一幀紅外數據的開始。在外部中斷 0 子程序中判斷引導碼的正確性,判讀的方法為通過定時器計數來計算高低電平持續的時間,并分別與引導碼規定時間進行對比。當超出了規定時間范圍,我們認為這不是一幀標準的紅外遙控數據,便直接返回跳出中斷子程序。當符合要求后,繼續往下執行,并判斷和接收 4 個字節的數據,將接收到的數據存放到指定存儲變量中,并置位紅外標志位。在主程序中查詢這個標志位來確定是否收到了紅外數據,將數據從存儲變量中取出,并將數據顯示在602液晶模塊上。為了方便后續使用,將紅外初始化,以及紅外中斷子程序放入"HongWai.h","HongWai.c"文件中。
"HongWai.h"代碼如下:
#ifndef __IR_H__
#define __IR_H__
extern void InitIR(); //初始化定時器TR0,外部中斷0
extern bit Flag_IR; //按鍵標志位
extern unsigned long Data_IR;//4個字節的數據:[31:0]數據反碼- >數據碼- >用戶反碼- >用戶碼
#endif
"HongWai.c"代碼如下:
#include< reg52.h >
#define HIGH_IR 1 //高電平
#define LOW_IR 0 //低電平
#define Min_9ms 8000 //8ms
#define Max_9ms 10000 //10ms
#define Min_4_5ms 3500 //3.5ms
#define Max_4_5ms 5000 //5ms
#define Min_560us 300 //300us
#define Max_560us 700 //700us
#define Min_1680us 1300 //1.3ms
#define Max_1680us 1800 //1.8ms
#define Time_16ms 16000 //16ms
sbit Led1 = P1^1;
sbit IR_in = P3^2;//紅外接收引腳,也是外部中斷0輸入腳
bit Flag_IR = 0;//紅外接收標志,收到正確幀數據后,由程序置1
unsigned long Data_IR;//4個字節的數據:[31:0]數據反碼- >數據碼- >用戶反碼- >用戶碼
//紅外接收初始化
void InitIR()
{
IR_in = 1;//釋放
TMOD &= 0xF0;//清零T0控制位
TMOD |= 0x01;//配置T0為模式1
TR0 = 0; //停止T0記數
ET0 = 0;//關定時器0中斷
IT0 = 1;//設置INT0為下降沿觸發
EX0 = 1;//開INT0中斷
EA=1; //開總中斷
}
unsigned int T_Count(bit flag)//電平計時器
{
TH0 = 0; //清零T0
TL0 = 0;
TR0 = 1;//啟動T0
//判斷高電平是否超過16ms,若超過定義為異常,直接跳出循環,防止進入死循環
while(IR_in==flag){if(TH1 >= (Time_16ms >>8)) break;}
TR0 = 0;
return (TH0*256 + TL0);//返回計數值,數值單位為us
}
//外部中斷0,中斷子程序,下降沿觸發進入中斷
void Int0() interrupt 0
{
unsigned int i;
unsigned int T_Low,T_High;
T_Low = T_Count( LOW_IR);//接收9ms的引導碼低電平
T_High = T_Count(HIGH_IR);//接收4.5ms引導碼高電平
//判斷引導碼正確性
if(T_Low< Min_9ms || T_Low >Max_9ms || T_High< Min_4_5ms || T_High >Max_4_5ms){IE0=0; return;}
//接收4個字節的數據,共32位
for(i=0;i< 32;i++)
{
T_Low = T_Count( LOW_IR);//接收560us位低電平
T_High = T_Count(HIGH_IR);//接收560us或1680us位高電平
//判讀位電平的正確性
if(T_Low< Min_560us || T_Low >Max_560us || T_High< Min_560us || T_High >Max_1680us) {IE0=0;return;}
Data_IR >>=1; //為0時高位補0
if(T_High >Min_1680us) Data_IR |= 0x80000000;//為1時高位置1
}
Flag_IR = 1; //接收到按鍵值后,置位
Led1 = 0;//閃爍小燈
//for(i=0;i< 5000;i++);
Led1 = 1;
IE0=0;//清楚中斷標志位,確保在響應外部中斷0過程中產生的外部中斷請求不再被響應。
}
在主程序中判斷數據標志位是否置1,并將接收到的數據顯示出來,主程序如下所示:
#include< reg52.h >
#include"HongWai.h"
#include"Drive_1602.h"
sbit DU = P2^7;//數碼管段選、位選引腳定義
sbit WE = P2^6;
unsigned char *Key_Str=0;
void main()
{
unsigned char Key;
Init_1602();//1602初始化
P0 = 0xff;//關閉所有數碼管
WE = 1;
WE = 0;
InitIR();
while(1)
{
if(Flag_IR)
{
Flag_IR = 0;
Key = (unsigned char)(Data_IR >>16);//數據碼
switch(Key)
{
case 69:Key_Str = "CH-";break;
case 70:Key_Str = "CH";break;
case 71:Key_Str = "CH+";break;
case 68:Key_Str = "PREV";break;
case 64:Key_Str = "NEXT";break;
case 67:Key_Str = "PLAY/PAUSE";break;
case 7:Key_Str = "-";break;
case 21 :Key_Str = "+";break;
case 9:Key_Str = "EQ";break;
case 22:Key_Str = "0";break;
case 25:Key_Str = "100+";break;
case 13:Key_Str = "200+";break;
case 12:Key_Str = "1";break;
case 24:Key_Str = "2";break;
case 94:Key_Str = "3";break;
case 8:Key_Str = "4";break;
case 28:Key_Str = "5";break;
case 90:Key_Str = "6";break;
case 66:Key_Str = "7";break;
case 82:Key_Str = "8";break;
case 74:Key_Str = "9";break;
default:Key_Str = "error!";
}
Disp_1602_str(2,1," ");
Disp_1602_str(2,1,Key_Str);
}
}
}
14.4 本章小結
本章介紹了紅外遙控器的發送和接收原理,并編寫了單片機接收紅外數據的驅動程序,后續可直接調用函數應用到具體的工程中去了。
-
單片機
+關注
關注
6039文章
44574瀏覽量
636323 -
無線通信
+關注
關注
58文章
4585瀏覽量
143631 -
紅外遙控器
+關注
關注
3文章
133瀏覽量
21691 -
外部中斷
+關注
關注
1文章
132瀏覽量
15837
發布評論請先 登錄
相關推薦
評論