紅外線,簡(jiǎn)稱(chēng)IR,是一種無(wú)線通訊方式,可以進(jìn)行無(wú)線數(shù)據(jù)的傳輸。
紅外射線(IR)或者單獨(dú)成為紅外線是指那些能量在電磁波頻譜范圍內(nèi),波長(zhǎng)比可見(jiàn)光略長(zhǎng)的,但是又比無(wú)線電波波長(zhǎng)短的射線。相應(yīng)地,紅外線的頻率高于微波,但是低于可見(jiàn)光。紅外光的波長(zhǎng)在幾個(gè)微米(符號(hào)μ,1μ=10-6m)或者納米范圍內(nèi)(縮寫(xiě)為nm,1nm=10-9m=0.001μ)。
科學(xué)家們將紅外光譜分成三個(gè)區(qū)域:近紅外波段,其能量和波長(zhǎng)接近可見(jiàn)光,大約0.750~1.300μ(750~1300nm);中紅外波段,在1.300~3.000μ(1300~3000nm)范圍內(nèi);遠(yuǎn)紅外波段,3.000~14.000μ(3000~14000nm)范圍內(nèi)。
紅外線被用于各種無(wú)線通信、監(jiān)測(cè)和控制應(yīng)用。還有一些應(yīng)用包括家庭娛樂(lè)的遙控器、無(wú)線局域網(wǎng)、筆記本電腦和臺(tái)式電腦之間的鏈接、不用電線的調(diào)制解調(diào)器、動(dòng)作偵察器和火災(zāi)傳感器等。
1號(hào)單片機(jī)與紅外接收頭連接電路如圖所示,紅外接收頭一般都可互換使用。
程序如下:
//////////////////////////// main.c ////////////////////////////////////////
// 紅外接收數(shù)據(jù),中斷方式,并通過(guò)串口發(fā)送接收到的4字節(jié),晶振:22.118400 MHz
// 接收頭信號(hào)引腳P5.5,串口波特率9600
///////////////////////////////////////////////////////////////////////////
#include “STC15W4K.H”
sbit Ir_Pin = P3^6; // 紅外接收頭信號(hào)輸出腳
unsigned char Ir_Buf[4]; // 用于保存解碼結(jié)果
bit IRflag = 0; // 紅外接收標(biāo)志,收到一幀正確數(shù)據(jù)后置1
void UART_init(void) // 9600@22.1184MHz
{
//下面代碼設(shè)置定時(shí)器1
TMOD = 0x20; // 0010 0000 定時(shí)器1工作于方式2(8位自動(dòng)重裝方式)
TH1 = 0xFA; // 波特率:9600 /22.1184MHZ
TL1 = 0xFA; // 波特率:9600 /22.1184MHZ
TR1 = 1;
//下面代碼設(shè)置定串口
AUXR = 0x00; // 很關(guān)鍵,使用定時(shí)器1作為波特率發(fā)生器,S1ST2=0
SCON = 0x50; // 0101 0000 SM0.SM1=01(最普遍的8位通信),REN=1(允許接收)
}
// UART發(fā)送一字節(jié)
void UART_Send_Byte(unsigned char dat)
{
SBUF = dat;
while (TI == 0);
TI = 0; // 此句可以不要,不影響后面數(shù)據(jù)的發(fā)送,只供代碼查詢數(shù)據(jù)是否發(fā)送完成
}
// 獲取低電平時(shí)間 (其實(shí)是16位計(jì)數(shù)器的計(jì)數(shù)值,STC15系列定時(shí)器默認(rèn)為16位自動(dòng)重裝方式)
unsigned int Ir_Get_Low()
{
TL0 = 0; // 清空16位計(jì)數(shù)器0
TH0 = 0; // 清空16位計(jì)數(shù)器0
TR0 = 1; // 計(jì)數(shù)器0開(kāi)始運(yùn)行
while (!Ir_Pin && (TH0《0x80)); // 信號(hào)引腳變成高或低電平時(shí)間》17ms退出(只要》12ms即可)
// 0x8000=32768, 32768*0.54253uS=17777.62 uS
TR0 = 0; // 這里 ! 優(yōu)先級(jí)大于&&
return (TH0 * 256 + TL0); // 返回16位計(jì)數(shù)器的計(jì)數(shù)值。
}
// 獲取高電平時(shí)間(其實(shí)是16位計(jì)數(shù)器的計(jì)數(shù)值,STC15系列定時(shí)器默認(rèn)為16位自動(dòng)重裝方式)
unsigned int Ir_Get_High()
{
TL0 = 0; // 清空16位計(jì)數(shù)器0
TH0 = 0; // 清空16位計(jì)數(shù)器0
TR0 = 1;
while (Ir_Pin && (TH0《0x40)); // 信號(hào)引腳變成低電平或高電平時(shí)間》17ms退出
TR0 = 0;
return (TH0 * 256 + TL0);
}
// 外部中斷初始化
void int2_init() // P3.6引腳即為外部中斷2
{
INT_CLKO|=0x10; // 開(kāi)啟外中斷2
EA = 1; // 總開(kāi)關(guān)
}
void int2_isr() interrupt 10 // 外部中斷2中斷函數(shù)
{
unsigned char i,j;
unsigned char DAT; // 臨時(shí)存放接收到的字節(jié),接收字節(jié)無(wú)誤后再存入數(shù)組使用
unsigned int time;
// 接收并判定引導(dǎo)碼的9ms 低電平
time = Ir_Get_Low();
if ((time 《 15667) || (time 》 17510))
{ // 引導(dǎo)脈沖低電平8500~9500us,T=12/22.1184=0.54253uS
// 8500/0.54253uS=15667.3 9500/0.54253uS=17510.5
IE1 = 0; // 退出前清除可能新的一次INT1 外中斷引發(fā)的標(biāo)志
return;
}
// 接收并判定引導(dǎo)碼的4.5ms 高電平
time = Ir_Get_High();
if ((time 《 7372) || (time 》 9216)) //引導(dǎo)脈沖高電平4000~5000us
{ // 4000/0.54253uS=7372.8 5000/0.54253uS=9216
IE1 = 0; // 退出前清除可能新的一次INT1 外中斷引發(fā)的標(biāo)志
return;
}
// 接收后續(xù)的4 字節(jié)數(shù)據(jù)
for (i=0; i《4; i++) // 循環(huán)接收4 個(gè)字節(jié)
{
for (j=0; j《8; j++) // 每個(gè)字節(jié)8位
{
time = Ir_Get_Low(); // 接收每位560us 低電平
if ((time 《 626) || (time 》 1438)) // 340~780us
{ // 340/0.54253uS=626.7 780/0.54253uS=1437.7
IE1 = 0; // 退出前清除可能新的一次INT1 外中斷引發(fā)的標(biāo)志
return;
}
time = Ir_Get_High(); // 接收每位560us或1690us高電平時(shí)間
if ((time》626) && (time《1438)) // 時(shí)間范圍為340-780us(中心值560us)
{
DAT 》》= 1; // 因低位在先,所以數(shù)據(jù)右移,移入的最高位為0
}
else if ((time》2728) && (time《3502)) // 時(shí)間判定范圍為1480~1900us(中心值1690us)
{ // 1480/0.54253uS=2727.9 1900/0.54253uS=3502.1
DAT 》》= 1; // 因低位在先,所以數(shù)據(jù)右移,移入的最高位為0
DAT |= 0x80; // 最高位置1
}
else // 不在上述范圍內(nèi)則說(shuō)明為誤碼,直接退出
{
IE1 = 0; // 退出前清除可能新的一次INT1 外中斷引發(fā)的標(biāo)志
return;
}
} // 單個(gè)字節(jié)處理完畢
Ir_Buf[i]=DAT; // 傳輸正確后才放入數(shù)組
}
IRflag = 1; // 接收完畢后設(shè)置標(biāo)志
IE1 = 0; // 退出前清除可能新的一次INT1 外中斷引發(fā)的標(biāo)志
}
void main()
{
UART_init();; // 串口初始化
int2_init(); // 外中斷 2 初始化(紅外接收引腳)
while (1)
{
if (IRflag) // 接收到紅外數(shù)據(jù)時(shí)發(fā)計(jì)算機(jī)顯示
{
IRflag = 0;
UART_Send_Byte(Ir_Buf[0]); // 用戶碼低字節(jié)
UART_Send_Byte(Ir_Buf[1]); // 用戶碼高字節(jié)
UART_Send_Byte(Ir_Buf[2]); // 鍵碼
UART_Send_Byte(Ir_Buf[3]); // 鍵反碼
}
}
}
評(píng)論
查看更多