#include "main.h"#include "port.h"#include "debug.h"/*----------------------------------------------改進(jìn)自xwj的程序。2007年10月2日版本1.0.1 www.mcukf.com紅外線(xiàn)接引腳于P3.2用我家的VCD遙控器調(diào)試成功。VCD遙控器 (上面無(wú)牌號(hào)) //================================================== 紅外線(xiàn)遙控器按鍵檢測(cè)程序.通過(guò)檢測(cè)兩次下降沿之間的時(shí)間差判斷接受到的數(shù)據(jù)位.已經(jīng)通過(guò)了測(cè)試,能夠正確區(qū)分出32bit數(shù)據(jù)的遙控器按鍵鍵值.具有數(shù)據(jù)重發(fā)功能,但是數(shù)據(jù)的重發(fā)有點(diǎn)頻繁.使用晶震頻率為11.0592MHz,所有定時(shí)值都是基于這個(gè)頻率計(jì)算.占用很少量的CPU時(shí)間,使用了外部中斷0接受數(shù)據(jù),定時(shí)器0進(jìn)行計(jì)數(shù),定時(shí)器1作為串口的波特率發(fā)生器(Band = 9600).主函數(shù)會(huì)使MCU進(jìn)入低功耗模式,如需加入自己的代碼需要屏蔽此功能.狀態(tài)機(jī): 1.如果時(shí)間差=0,由空閑態(tài)進(jìn)入接受態(tài) 2.如果時(shí)間差>1ms and <1.3ms,收到數(shù)據(jù)0 3.如果時(shí)間差>2ms and <2.5ms,收到數(shù)據(jù)1 4.如果時(shí)間差>13.2ms and <13.8ms,收到開(kāi)始位 5.如果時(shí)間差>12.2ms and <12.8ms,收到停止位(沒(méi)有檢測(cè)) 6.如果時(shí)間定時(shí)器溢出(時(shí)間差>20ms),進(jìn)入空閑狀態(tài)-------------------------------------------------*/ //11.0592晶振#define TIME_0_00MS 0x0000#define TIME_1_00MS 0x039a#define TIME_1_13MS 0x0480#define TIME_2_00MS 0x0733#define TIME_2_50MS 0x0900#define TIME_13_2MS 0x2ecd#define TIme_11_ms (TIME_13_2MS-TIME_2_50MS )#define TIME_20_0MS 0x47ff#define TIME1_LOAD (0xffff - TIME_20_0MS)unsigned char Irdat;bit Irok,running;uchar IrCode[4];uchar irCodeIndex=0;void IrInit(void) //遙控接收初始化{ //-----init TIME0---- TMOD &=0xf0; TMOD |= 0x01; //TMOD T0,T1均選用方式1(16位定時(shí)) TH0 = TIME1_LOAD >> 8; TL0 = TIME1_LOAD & 0xff; IP|=0x01; //SETB INT0 中斷優(yōu)先 //TCON |= 0x41; IT0=1; //TCON EX0下降沿觸發(fā),啟動(dòng)T1 // TR0 = 1; EX0=1; EA=1; ET0=1; //SETB EX0 0x1 外部中斷 0 允許 //SETB ET0 0x8 定時(shí)器 1 中斷允許 //SETB EA 0x80 開(kāi)中斷}unsigned char IrGetcode(void)//返回遙控碼{ Irok=0; return(Irdat);}bit IrTest(void)//檢查有無(wú)遙控信號(hào){ return Irok;}void int0_isr(void) interrupt 0 using 1 //遙控使用外部中斷0,接P3.2口{ unsigned int timer; TR0 = 0; timer = ((TH0 << 8) | TL0) - TIME1_LOAD; TH0 = TIME1_LOAD >> 8; TL0 = TIME1_LOAD & 0xff; TR0 = 1; DebugPin=0; if(timer > TIME_1_00MS && timer < TIME_1_13MS)//data 0 { IrCode[irCodeIndex/8]<<=1; irCodeIndex++ ; if(irCodeIndex>=15)running=1; } else if(timer > TIME_2_00MS && timer < TIME_2_50MS)//data 1 { IrCode[irCodeIndex/8]<<=1; IrCode[irCodeIndex/8]+=1; irCodeIndex++; if(irCodeIndex>=15)running=1; } else if(timer == TIME_0_00MS || timer > TIME_13_2MS) { IrCode[0]=0; IrCode[1]=0; IrCode[2]=0; IrCode[3]=0; irCodeIndex=0; } else if(timer < TIME_13_2MS && timer > TIme_11_ms && running==0)//自動(dòng)重發(fā)功能。 { Irok=1; } }void time0_isr(void) interrupt 1 using 1 //遙控使用定時(shí)計(jì)數(shù)器1{ TR0 = 0; DebugPin=1; TH0 = TIME1_LOAD >> 8; TL0 = TIME1_LOAD & 0xff; if (IrCode[2] == (~IrCode[3])) { Irdat = IrCode[2]; Irok = 1; running=0; } else { Irok = 0; }}void main(void){ IrInit(); initUartT1(); EA=1; //Inituart(1200); while(1) { if (IrTest()) { outPutAscii(IrGetcode()); // 在串行口 輸出遙控碼 // IrGetcode(); DebugPin=0; //接的一個(gè)LED,遙于調(diào)試和接收指示 } else { DebugPin=1; } PCON |=0x01; }} |