?? 紅外接受編碼的程序.txt
字號:
這是一個紅外接受編碼的程序,發送器為NB9148,接受器為通用紅外接受模塊,軟件解碼
用的單片P87LPC762,接收器連單片機的INT1端口。是不是有什么問題呀,我覺得第一:沒
有定時初值,然后最關鍵的是怎么處理中斷相應的時間問題呢,這樣編程不會漏掉信號
嗎?請大家幫我看看,晶振11.0592
#include <REG768.H> /*Philips 87LPC768 寄存器定義頭文件*/
#define REDINT 0x06 /*紅外線間隔*/
/*存放消息標志的可位尋址字節Message,Message=NULL 時無任消息*/
unsigned char bdata Message;
/*在接收過程中置位,檢測標置位Get 可以有效防止其它進程干擾接收,防止數據丟失.*/
sbit RedMsg=Message^0; /*紅外遙控消息*/
sbit RedRead=Message^1; /*位接收過程標志*/
sbit RedBit =Message^2; /*接收到的位值*/
sbit RSend =Message^3; /*紅外接收中重新發送標志*/
/*存放遙控的字數據,低4 位存放接收到的bit 的位移,高12 位從低到高存放接收到的
bit*/
unsigned char bdata RedDataL,RedDataH;
/*RedDataH 字節低6 位代表指令只有一個1 C1-C3 是用戶碼H 表示連續S1 S2 分別表示第
一二組單發*/
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; /*狀態字節*/
sbit RedControl=State^6; /*遙控狀態*/
/*定時器T00 的高位定時參數為Timer 定時256*Timer+(80--336)個周期共139Timer+(43--
182)us<37ms 定時器T01
的高位定時節參數為nTimer 定時256*nTimer+(24--280)個周期139nTimer+(13--152)
us<9.1s,RedCon 存放紅外接收時的載
波計數*/
unsigned char data RedCon,Timer;
unsigned int nTimer; /*定時整型參數*/
void main()
{
IEN0=0x14; /*只打開INT1 中斷*/
WDRST=0x1E; /*看門狗清0*/
WDRST=0xE1;
WDCON=0x12; /*40-90ms 看門狗(>最大延時37ms)*/
TCON=0x40; /*定時器1 開始工作, INT1 低電平觸發*/
TMOD=0x23; /*定時器0 擴展成兩個8 位定時器T00 和T01 用于同步控制*/
if((WDCON&0x30)!=0x30){ /*看門狗陷阱復位時無需初始化*/
Message=0; /*無消息*/
State=0; /*正常復位無任何狀態*/
}
while(1){ /*消息循環*/
WDRST=0x1E; /*看門狗清0*/
WDRST=0xE1;
EX1= RedControl; /*設置遙控中斷INT1 */
if(RedMsg) { /*執行遙控指令*/
EX1=0; /*在指令沒有處理完之前不能重復中斷*/
switch(RedDataH){ /*這里加入紅外指令的控制過程*/
case 0x82: /*Channel 1*/
break;
case 0xA0: /*Channel 2*/
break;
/*……*/
}
EX1=1;
RedDataL=0; /*復位紅外數據*/
RedDataH=0; /*復位紅外數據*/
RedMsg=0;} /*復位紅外遙控消息*/
}
}
void Count0(void) interrupt 1 using 3
{ /*定時器T00 中斷,最大定時37ms*/
if(Timer!=0){ /*檢測定時器T00 的擴展高位*/
Timer--;
return;}
}
/*INT1 用于紅外解碼狀態遙控解碼數據處理,nTimer=1 定時152--291us*/
void Inte1() interrupt 2 using 2
{
for(nTimer=8;nTimer>1;nTimer--);/*使處理周期達到51 機器周期=27.7us 使得
RedCon<32*/
if(RedRead) RedCon++; /*0 信號寬度a=420us,1 信號寬度a=1260us,周期4a=1680us*/
else{ /*開始計數或者重新發送時開始計數*/
RedBit=0; /*復位接收位*/
RedCon=0; /*復位載波計數*/
RedRead=1; /*置位位接收標志*/
if(!ET1){ /*首次接收時沒有啟動定時器T01 接收第一個位*/
TF1=0; /*復位定時器T01 益出標志*/
ET1=1; /*啟動T01 定時*/
RedDataL=0; /*復位紅外數據*/
RedDataH=0; /*復位紅外數據*/
RSend=0;} /*復位重新發送標志*/
}
}
void Count1(void) interrupt 3 using 3
{ /*定時器T01 中斷,最大定時9.1s*/
if(nTimer!=0){ /*檢測定時器T01 的擴展高位*/
nTimer--;
return;}
ET1=0; /*關閉T01 定時*/
if(RedRead){ /*紅外接收狀態*/
if((RedDataL&0xF)==12){ /*第一階段接收已經結束*/
RSend=1; /*置位重新發送標志以便校驗*/
RedDataL&=0xF0;} /*復位位指針以便校驗*/
if(RedCon>27-REDINT&&RedCon<27+REDINT) RedBit=1;
else RedBit=0; /*低電平計數9 表示0 27 表示1*/
if(RSend){ /*檢驗重復發送的數據是否與第一次符合*/
switch(RedDataL&0xF){
case 0: /*檢驗重復發送的第1 位數據*/
if(RedBit!=RedData0) goto RClear;
break;
case 1: /*檢驗重復發送的第2 位數據*/
if(RedBit!=RedData1) goto RClear;
break;
case 2: /*檢驗重復發送的第3 位數據*/
if(RedBit!=RedData2) goto RClear;
break;
case 3: /*檢驗重復發送的第4 位數據*/
if(RedBit!=RedData3) goto RClear;
break;
case 4: /*檢驗重復發送的第5 位數據*/
if(RedBit!=RedData4) goto RClear;
break;
case 5: /*檢驗重復發送的第6 位數據*/
if(RedBit!=RedData5) goto RClear;
break;
case 6: /*檢驗重復發送的第7 位數據*/
if(RedBit!=RedData6) goto RClear;
break;
case 7: /*檢驗重復發送的第8 位數據*/
if(RedBit!=RedData7) goto RClear;
break;
case 8: /*檢驗重復發送的第9 位數據*/
if(RedBit!=RedData8) goto RClear;
break;
case 9: /*檢驗重復發送的第10 位數據*/
if(RedBit!=RedData9) goto RClear;
break;
case 10: /*檢驗重復發送的第11 位數據*/
if(RedBit!=RedData10) goto RClear;
break;
case 11: /*檢驗重復發送的第12 位數據*/
if(RedBit!=RedData11) goto RClear;
RedMsg=1; /*接受到經過檢驗正確的編碼后置位遙控消息*/
RedBit=0; /*復位接收位*/
RSend=0; /*復位重新發送標志*/
RedRead=0; /*復位接收過程標志*/
RedCon=0; /*復位載波計數*/
return;
default: /*重復發送的數據多于12 位時判斷為錯誤*/
goto RClear;
}
}
else{
switch(RedDataL&0xF){
case 0: /*保存首次發送的第1 位數據*/
RedData0=RedBit;
break;
case 1: /*保存首次發送的第2 位數據*/
RedData1=RedBit;
break;
case 2: /*保存首次發送的第3 位數據*/
RedData2=RedBit;
break;
case 3: /*保存首次發送的第4 位數據*/
RedData3=RedBit;
break;
case 4: /*保存首次發送的第5 位數據*/
RedData4=RedBit;
break;
case 5: /*保存首次發送的第6 位數據*/
RedData5=RedBit;
break;
case 6: /*保存首次發送的第7 位數據*/
RedData6=RedBit;
break;
case 7: /*保存首次發送的第8 位數據*/
RedData7=RedBit;
break;
case 8: /*保存首次發送的第9 位數據*/
RedData8=RedBit;
break;
case 9: /*保存首次發送的第10 位數據*/
RedData9=RedBit;
break;
case 10: /*保存首次發送的第11 位數據*/
RedData10=RedBit;
break;
case 11: /*保存首次發送的第12 位數據*/
RedData11=RedBit;
break;
default: /*首次發送的數據多于12 位時判斷為錯誤*/
goto RClear;
}
}
RedDataL++; /*位位移加1*/
RedBit=0; /*復位接收位*/
RedRead=0; /*復位接收過程標志*/
RedCon=0; /*復位載波計數*/
nTimer=423; /*用定時140a 檢測同步信號208a*/
TF1=0; /*復位定時器T01 益出標志*/
ET1=1;} /*啟動定時器*/
else if(RSend){ /*在位接收沒有結束時發生定時中斷需要復位接收信息(同步)*/
RClear:
RedDataL=0; /*復位紅外數據*/
RedDataH=0; /*復位紅外數據*/
RedBit=0; /*復位接收位*/
RedRead=0; /*復位接收過程標志*/
RSend=0; /*復位重新發送標志*/
RedCon=0; /*復位載波計數*/
ET1=0; /*關閉T01 定時*/
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -