概述
本章介紹紅外遙控通信試驗,通過本章的學(xué)習(xí)掌握紅外遙控器的編碼原理以及使用。在 RY-51 單片機開發(fā)板上,配備了一個紅外信號接收頭,用于接收紅外信號,與開發(fā)板配套了一個紅外遙控器,用于發(fā)送紅外數(shù)據(jù)。
14.1 紅外遙控原理簡介
紅外遙控是一種無線、非接觸式數(shù)據(jù)傳輸技術(shù)、具有成本低、抗干擾能力強的短距離通信技術(shù)、被廣泛的應(yīng)用于電子設(shè)備遙控通信中,包括電視、空調(diào)、手機等多種電子設(shè)備中,具有廣泛的應(yīng)用前景。
紅外通信原理為將信息加載到紅外光波中,利用發(fā)射裝置發(fā)射出去,接收設(shè)備接收到紅外光后將信息解碼并做出相應(yīng)的操作,便完成了一次紅外光通信。我們以一個生活中常見的例子為例,當(dāng)兩個在黑暗中的人,一人拿著手電筒通過不停的開關(guān)閃爍手電筒將信息傳遞給對方。而我們這里使用的是紅外光,它的優(yōu)點為紅外光不可見,對周圍環(huán)境影響較小,另外由于紅外光波長遠小于其它常用無線電波長,因此,對其它無線通信電子設(shè)備無影響。怎樣將信息加載到紅外光上呢?這就是我們常說的紅外遙控編碼協(xié)議了,目前常用的有 Philips RC-5Protocol、Sharp 協(xié)議、NEC 協(xié)議等。我們這例重點講解 NEC 協(xié)議。
在數(shù)字通信中最小的信息單位為位,即為“0”或“1”,那么在紅外通信協(xié)議中是怎么表示邏輯“0”和“1”的呢?該協(xié)議中以發(fā)射紅外載波的占空比代表信息“0”和“1”。邏輯“0”的表示法為:560us 的連續(xù)載波 +560us 的低電平,總時長為 1.125ms。邏輯“1”的表示法為:560us 的連續(xù)載波 +1680us 的低電平,總時長為 2.25ms。其中載波為 38KHz 的方波,邏輯“0”和邏輯“1”表示法如下圖所示:
圖 14-1 NEC 協(xié)議邏輯“0”和邏輯“1”表示法
傳輸一幀 NEC 格式的數(shù)據(jù)包括以下內(nèi)容:
1) 同步碼頭:9ms 載波 +4.5ms 低電平;
2. 用戶碼:用戶自定義的 8bit 數(shù)據(jù);
3. 用戶反碼:8bit 用戶碼按位取反;
4. 數(shù)據(jù)碼:8bit 數(shù)據(jù),也稱為 8 位按鍵數(shù)據(jù)碼;
5. 數(shù)據(jù)反碼:8bit 數(shù)據(jù)碼按位取反。
由上面內(nèi)容可知,實際傳輸?shù)臄?shù)據(jù)內(nèi)容為用戶碼和數(shù)據(jù)碼,上面的反碼用于數(shù)據(jù)校驗,確保數(shù)據(jù)傳輸?shù)目煽啃裕瑪?shù)據(jù)按低位到高位的順序一次傳輸。傳輸一幀 NEC 數(shù)據(jù)格式如下圖所示:
上圖為 NEC 發(fā)送模塊通過紅外光發(fā)送的數(shù)據(jù),當(dāng)接收模塊接收到 38KHz 的載波時輸出低電平,其它情況輸出高電平,因此,單片機通過測量接收到的電平高低持續(xù)時間便可解碼數(shù)據(jù)了。例如當(dāng)單片機接收到 9ms 低電平 +4.5ms 高電平時,即接收到了引導(dǎo)碼,當(dāng)接收到 560us 低電平 +560us 高電平表示接收到了數(shù)據(jù)“0”,當(dāng)接收到 560us 低電平 +1680us 高電平表示接收到了數(shù)據(jù)“1”,依照上述模式便可完成一幀數(shù)據(jù)的接收。
14.2 紅外接收硬件電路設(shè)計
RY-51 單片機開發(fā)板載了紅外信號接收模塊 VS1838B,模塊外形圖下圖左邊所示,電路連接圖如下圖右邊所示。其中,輸出引腳與單片機的 P3.2 引腳相連接,同時該引腳為單片機的外部中斷 0 輸入引腳。因此,可以利用單片機的外部中斷 0 來處理紅外數(shù)據(jù)接收。
14.3 紅外解碼試驗
紅外解碼軟件編寫步驟如下:首先進行初始化將外部中斷 0 設(shè)置為下降沿觸發(fā),當(dāng)接收到的紅外信號由高電平變?yōu)榈碗娖綍r,表明一幀紅外數(shù)據(jù)的開始。在外部中斷 0 子程序中判斷引導(dǎo)碼的正確性,判讀的方法為通過定時器計數(shù)來計算高低電平持續(xù)的時間,并分別與引導(dǎo)碼規(guī)定時間進行對比。當(dāng)超出了規(guī)定時間范圍,我們認(rèn)為這不是一幀標(biāo)準(zhǔn)的紅外遙控數(shù)據(jù),便直接返回跳出中斷子程序。當(dāng)符合要求后,繼續(xù)往下執(zhí)行,并判斷和接收 4 個字節(jié)的數(shù)據(jù),將接收到的數(shù)據(jù)存放到指定存儲變量中,并置位紅外標(biāo)志位。在主程序中查詢這個標(biāo)志位來確定是否收到了紅外數(shù)據(jù),將數(shù)據(jù)從存儲變量中取出,并將數(shù)據(jù)顯示在602液晶模塊上。為了方便后續(xù)使用,將紅外初始化,以及紅外中斷子程序放入"HongWai.h","HongWai.c"文件中。
"HongWai.h"代碼如下:
#ifndef __IR_H__
#define __IR_H__
extern void InitIR(); //初始化定時器TR0,外部中斷0
extern bit Flag_IR; //按鍵標(biāo)志位
extern unsigned long Data_IR;//4個字節(jié)的數(shù)據(jù):[31:0]數(shù)據(jù)反碼- >數(shù)據(jù)碼- >用戶反碼- >用戶碼
#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;//紅外接收標(biāo)志,收到正確幀數(shù)據(jù)后,由程序置1
unsigned long Data_IR;//4個字節(jié)的數(shù)據(jù):[31:0]數(shù)據(jù)反碼- >數(shù)據(jù)碼- >用戶反碼- >用戶碼
//紅外接收初始化
void InitIR()
{
IR_in = 1;//釋放
TMOD &= 0xF0;//清零T0控制位
TMOD |= 0x01;//配置T0為模式1
TR0 = 0; //停止T0記數(shù)
ET0 = 0;//關(guān)定時器0中斷
IT0 = 1;//設(shè)置INT0為下降沿觸發(fā)
EX0 = 1;//開INT0中斷
EA=1; //開總中斷
}
unsigned int T_Count(bit flag)//電平計時器
{
TH0 = 0; //清零T0
TL0 = 0;
TR0 = 1;//啟動T0
//判斷高電平是否超過16ms,若超過定義為異常,直接跳出循環(huán),防止進入死循環(huán)
while(IR_in==flag){if(TH1 >= (Time_16ms >>8)) break;}
TR0 = 0;
return (TH0*256 + TL0);//返回計數(shù)值,數(shù)值單位為us
}
//外部中斷0,中斷子程序,下降沿觸發(fā)進入中斷
void Int0() interrupt 0
{
unsigned int i;
unsigned int T_Low,T_High;
T_Low = T_Count( LOW_IR);//接收9ms的引導(dǎo)碼低電平
T_High = T_Count(HIGH_IR);//接收4.5ms引導(dǎo)碼高電平
//判斷引導(dǎo)碼正確性
if(T_Low< Min_9ms || T_Low >Max_9ms || T_High< Min_4_5ms || T_High >Max_4_5ms){IE0=0; return;}
//接收4個字節(jié)的數(shù)據(jù),共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;//清楚中斷標(biāo)志位,確保在響應(yīng)外部中斷0過程中產(chǎn)生的外部中斷請求不再被響應(yīng)。
}
在主程序中判斷數(shù)據(jù)標(biāo)志位是否置1,并將接收到的數(shù)據(jù)顯示出來,主程序如下所示:
#include< reg52.h >
#include"HongWai.h"
#include"Drive_1602.h"
sbit DU = P2^7;//數(shù)碼管段選、位選引腳定義
sbit WE = P2^6;
unsigned char *Key_Str=0;
void main()
{
unsigned char Key;
Init_1602();//1602初始化
P0 = 0xff;//關(guān)閉所有數(shù)碼管
WE = 1;
WE = 0;
InitIR();
while(1)
{
if(Flag_IR)
{
Flag_IR = 0;
Key = (unsigned char)(Data_IR >>16);//數(shù)據(jù)碼
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 本章小結(jié)
本章介紹了紅外遙控器的發(fā)送和接收原理,并編寫了單片機接收紅外數(shù)據(jù)的驅(qū)動程序,后續(xù)可直接調(diào)用函數(shù)應(yīng)用到具體的工程中去了。
-
單片機
+關(guān)注
關(guān)注
6030文章
44489瀏覽量
631968 -
無線通信
+關(guān)注
關(guān)注
58文章
4493瀏覽量
143345 -
紅外遙控器
+關(guān)注
關(guān)注
3文章
133瀏覽量
21628 -
外部中斷
+關(guān)注
關(guān)注
1文章
131瀏覽量
15790
發(fā)布評論請先 登錄
相關(guān)推薦
評論