?? p87lpc762+nb9148紅外線遙控.c
字號(hào):
//P87LPC762+NB9148紅外線遙控
//2006年8月
//Philips公司的51LPC系列
//NB9148為遙控發(fā)射專用電路,16引腳可形成18只按鍵
//NB9149為遙控接收專用電路,可完成10個(gè)功能控制
//NB9150為遙控接收專用電路,可完成18個(gè)功能控制
//本實(shí)驗(yàn)的遙控接收采用通用的紅外線接收頭
//遙控接收接8腳P1_4的INT1輸入口;晶振為11.0592MHz
#include <REG768.H> //87LPC768寄存器定義頭文件
#include <stdio.h>
#include <intrins.h>
#define REDINT 0x06 //紅外線間隔
//存放消息標(biāo)志的可位尋址字節(jié)Message,Message=NULL時(shí)無任消息
unsigned char bdata Message;
//在接收過程中置位,檢測標(biāo)置位Get可以有效防止其它進(jìn)程干擾接收,防止數(shù)據(jù)丟失
sbit RedMsg =Message^0; //紅外遙控消息
sbit RedRead=Message^1; //位接收過程標(biāo)志
sbit RedBit =Message^2; //接收到的位值
sbit RSend =Message^3; //紅外接收中重新發(fā)送標(biāo)志
//存放遙控的字?jǐn)?shù)據(jù),低4位存放接收到的bit的位移,高12位從低到高存放接收到的bit
unsigned char bdata RedDataL,RedDataH;
//RedDataH字節(jié)低6位代表指令,只有一個(gè)1,C1~C3是用戶碼,H表示連續(xù),S1S2分別表示第一二組單發(fā)
sbit RedData0=RedDataL^4; //C1
sbit RedData1=RedDataL^5; //C2
sbit RedData2=RedDataL^6; //C3
sbit RedData3=RedDataL^7; //H
sbit RedData11=RedDataH^0; //D6
sbit RedData10=RedDataH^1; //D5
sbit RedData9=RedDataH^2; //D4
sbit RedData8=RedDataH^3; //D3
sbit RedData7=RedDataH^4; //D2
sbit RedData6=RedDataH^5; //D1
sbit RedData5=RedDataH^6; //S2
sbit RedData4=RedDataH^7; //S1
unsigned char bdata State; //狀態(tài)字節(jié)
sbit RedControl=State^6; //遙控狀態(tài)
//定時(shí)器T00的高位定時(shí)參數(shù)為Timer,定時(shí)256*Timer+(80--336)個(gè)周期,共139Timer+(43~
//182)us<37ms。定時(shí)器T01的高位定時(shí)節(jié)參數(shù)為nTimer,定時(shí)256*nTimer+(24~280)個(gè)周期,
//139nTimer+(13~152)us<9.1s。RedCon存放紅外接收時(shí)的載波計(jì)數(shù)
unsigned char data RedCon,Timer;
unsigned int nTimer; //定時(shí)整型參數(shù)
void Count0(void) interrupt 1 using 3 //定時(shí)器T00中斷,最大定時(shí)37ms
{if(Timer!=0) //檢測定時(shí)器T00的擴(kuò)展高位
{Timer--;
return;
}
}
//INT1用于紅外解碼狀態(tài)遙控解碼數(shù)據(jù)處理,nTimer=1定時(shí)152~291us
void Inte1() interrupt 2 using 2
{for(nTimer=8;nTimer>1;nTimer--); //使處理周期達(dá)到51機(jī)器周期=27.7us使得RedCon<32
if(RedRead) RedCon++; //0信號(hào)寬度a=420us,1信號(hào)寬度a=1260us,周期4a=1680us
else //開始計(jì)數(shù)或者重新發(fā)送時(shí)開始計(jì)數(shù)
{RedBit=0; //復(fù)位接收位
RedCon=0; //復(fù)位載波計(jì)數(shù)
RedRead=1; //置位位接收標(biāo)志
if(!ET1) //首次接收時(shí)沒有啟動(dòng)定時(shí)器T01接收第一個(gè)位
{TF1=0; //復(fù)位定時(shí)器T01溢出標(biāo)志
ET1=1; //啟動(dòng)T01定時(shí)
RedDataL=0; //復(fù)位紅外數(shù)據(jù)
RedDataH=0; //復(fù)位紅外數(shù)據(jù)
RSend=0; //復(fù)位重新發(fā)送標(biāo)志
}
}
}
void Count1(void) interrupt 3 using 3 //定時(shí)器T01中斷,最大定時(shí)9.1s
{if(nTimer!=0) //檢測定時(shí)器T01的擴(kuò)展高位
{nTimer--;
return;
}
ET1=0; //關(guān)閉T01定時(shí)
if(RedRead) //紅外接收狀態(tài)
{if((RedDataL&0xF)==12) //第一階段接收已經(jīng)結(jié)束
{RSend=1; //置位重新發(fā)送標(biāo)志以便校驗(yàn)
RedDataL&=0xF0; //復(fù)位位指針以便校驗(yàn)
}
if(RedCon>27-REDINT&&RedCon<27+REDINT)
RedBit=1;
else RedBit=0; //低電平計(jì)數(shù)9表示0 27表示1
if(RSend) //檢驗(yàn)重復(fù)發(fā)送的數(shù)據(jù)是否與第一次符合
{switch(RedDataL&0xF)
{case 0: //檢驗(yàn)重復(fù)發(fā)送的第1位數(shù)據(jù)
if(RedBit!=RedData0) goto RClear;
break;
case 1: //檢驗(yàn)重復(fù)發(fā)送的第2位數(shù)據(jù)
if(RedBit!=RedData1) goto RClear;
break;
case 2: //檢驗(yàn)重復(fù)發(fā)送的第3位數(shù)據(jù)
if(RedBit!=RedData2) goto RClear;
break;
case 3: //檢驗(yàn)重復(fù)發(fā)送的第4位數(shù)據(jù)
if(RedBit!=RedData3) goto RClear;
break;
case 4: //檢驗(yàn)重復(fù)發(fā)送的第5位數(shù)據(jù)
if(RedBit!=RedData4) goto RClear;
break;
case 5: //檢驗(yàn)重復(fù)發(fā)送的第6位數(shù)據(jù)
if(RedBit!=RedData5) goto RClear;
break;
case 6: //檢驗(yàn)重復(fù)發(fā)送的第7位數(shù)據(jù)
if(RedBit!=RedData6) goto RClear;
break;
case 7: //檢驗(yàn)重復(fù)發(fā)送的第8位數(shù)據(jù)
if(RedBit!=RedData7) goto RClear;
break;
case 8: //檢驗(yàn)重復(fù)發(fā)送的第9位數(shù)據(jù)
if(RedBit!=RedData8) goto RClear;
break;
case 9: //檢驗(yàn)重復(fù)發(fā)送的第10位數(shù)據(jù)
if(RedBit!=RedData9) goto RClear;
break;
case 10: //檢驗(yàn)重復(fù)發(fā)送的第11位數(shù)據(jù)
if(RedBit!=RedData10) goto RClear;
break;
case 11: //檢驗(yàn)重復(fù)發(fā)送的第12位數(shù)據(jù)
if(RedBit!=RedData11) goto RClear;
RedMsg=1; //接受到經(jīng)過檢驗(yàn)正確的編碼后置位遙控消息
RedBit=0; //復(fù)位接收位
RSend=0; //復(fù)位重新發(fā)送標(biāo)志
RedRead=0; //復(fù)位接收過程標(biāo)志
RedCon=0; //復(fù)位載波計(jì)數(shù)
return;
default: //重復(fù)發(fā)送的數(shù)據(jù)多于12位時(shí)判斷為錯(cuò)誤
goto RClear;
}
}
else
{switch(RedDataL&0xF)
{case 0: //保存首次發(fā)送的第1位數(shù)據(jù)
RedData0=RedBit;
break;
case 1: //保存首次發(fā)送的第2位數(shù)據(jù)
RedData1=RedBit;
break;
case 2: //保存首次發(fā)送的第3位數(shù)據(jù)
RedData2=RedBit;
break;
case 3: //保存首次發(fā)送的第4位數(shù)據(jù)
RedData3=RedBit;
break;
case 4: //保存首次發(fā)送的第5位數(shù)據(jù)
RedData4=RedBit;
break;
case 5: //保存首次發(fā)送的第6位數(shù)據(jù)
RedData5=RedBit;
break;
case 6: //保存首次發(fā)送的第7位數(shù)據(jù)
RedData6=RedBit;
break;
case 7: //保存首次發(fā)送的第8位數(shù)據(jù)
RedData7=RedBit;
break;
case 8: //保存首次發(fā)送的第9位數(shù)據(jù)
RedData8=RedBit;
break;
case 9: //保存首次發(fā)送的第10位數(shù)據(jù)
RedData9=RedBit;
break;
case 10: //保存首次發(fā)送的第11位數(shù)據(jù)
RedData10=RedBit;
break;
case 11: //保存首次發(fā)送的第12位數(shù)據(jù)
RedData11=RedBit;
break;
default: //首次發(fā)送的數(shù)據(jù)多于12位時(shí)判斷為錯(cuò)誤
goto RClear;
}
}
RedDataL++; //位位移加1
RedBit=0; //復(fù)位接收位
RedRead=0; //復(fù)位接收過程標(biāo)志
RedCon=0; //復(fù)位載波計(jì)數(shù)
nTimer=423; //用定時(shí)140a 檢測同步信號(hào)208a
TF1=0; //復(fù)位定時(shí)器T01益出標(biāo)志
ET1=1; //啟動(dòng)定時(shí)器
}
else if(RSend) //在位接收沒有結(jié)束時(shí)發(fā)生定時(shí)中斷需要復(fù)位接收信息(同步)
{RClear:
RedDataL=0; //復(fù)位紅外數(shù)據(jù)
RedDataH=0; //復(fù)位紅外數(shù)據(jù)
RedBit=0; //復(fù)位接收位
RedRead=0; //復(fù)位接收過程標(biāo)志
RSend=0; //復(fù)位重新發(fā)送標(biāo)志
RedCon=0; //復(fù)位載波計(jì)數(shù)
ET1=0; //關(guān)閉T01定時(shí)
}
}
void main(void)
{
IEN0=0x14; //只打開INT1中斷
WDRST=0x1E; //看門狗清0
WDRST=0xE1;
WDCON=0x12; //40-90ms看門狗(>最大延時(shí)37ms)
TCON=0x40; //定時(shí)器1開始工作,INT1低電平觸發(fā)
TMOD=0x23; //定時(shí)器0擴(kuò)展成兩個(gè)8位定時(shí)器T00和T01用于同步控制
if((WDCON&0x30)!=0x30) //看門狗陷阱復(fù)位時(shí)無需初始化
{Message=0; //無消息
State=0; //正常復(fù)位無任何狀態(tài)
}
while(1) //消息循環(huán)
{WDRST=0x1E; //看門狗清0
WDRST=0xE1;
EX1=RedControl; //設(shè)置遙控中斷INT1
if(RedMsg) //執(zhí)行遙控指令
{EX1=0; //在指令沒有處理完之前不能重復(fù)中斷
switch(RedDataH) //這里加入紅外指令的控制過程
{case 0x82: //Channel 1
break;
case 0xA0: //Channel 2
break;
}
EX1=1;
RedDataL=0; //復(fù)位紅外數(shù)據(jù)
RedDataH=0; //復(fù)位紅外數(shù)據(jù)
RedMsg=0; //復(fù)位紅外遙控消息
}
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -