|
#include <reg52.h>
/*====================================
自定義類(lèi)型名
====================================*/
typedef unsigned char INT8U;
typedef unsigned char uchar;
typedef unsigned int INT16U;
typedef unsigned int uint;
/*====================================
硬件接口位聲明
====================================*/
sbit IR = P3^2; //定義紅外脈沖數(shù)據(jù)接口 外部中斷O輸入口
//sbit a=P0^0;
//sbit b=P0^1;
uchar code table[]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9};
uchar code table1[]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1};
uchar IRtime; //檢測(cè)紅外高電平持續(xù)時(shí)間(脈寬)
uchar IRcord[4]; //此數(shù)組用于儲(chǔ)存分離出來(lái)的4個(gè)字節(jié)的數(shù)據(jù)(用戶(hù)碼2個(gè)字節(jié)+鍵值碼2個(gè)字節(jié))
uchar IRdata[33]; //此數(shù)組用于儲(chǔ)存紅外的33位數(shù)據(jù)(第一位為引導(dǎo)碼用戶(hù)碼16+鍵值碼16)
bit IRpro_ok, IRok; //第一個(gè)用于紅外接收4個(gè)字節(jié)完畢。IRok用為檢測(cè)脈寬完畢
uchar o;
void init() //初始化定時(shí)器0 和外部中斷0
{
TMOD = 0x22; //定時(shí)器0和定時(shí)器1工作方式2,8位自動(dòng)重裝
TH0 = 0x00; //高8位裝入0那么定時(shí)器溢出一次的時(shí)間是256個(gè)機(jī)器周期
TL0 = 0x00;
EA = 1; //總中斷
ET0 = 1; //定時(shí)器0中斷
TR0 = 1; //啟動(dòng)定時(shí)器0
IT0 = 1; //設(shè)置外部中斷0為跳沿觸發(fā)方式,來(lái)一個(gè)下降沿觸發(fā)一次
EX0 = 1; //啟動(dòng)外部中斷0
TH1 = 0xfd; //此溢出率為波特率9600
TL1 = 0xfd;
TR1 = 1; //啟動(dòng)定時(shí)器1
SM1 = 1; //設(shè)置串口工作方式1,10位異步收發(fā)器
}
void delay(uchar z)
{
uchar x,y;
for(x=z;x>0;x--)
for(y=120;y>0;y--);
}
void time0() interrupt 1 //定義定時(shí)器0
{
IRtime++; //檢測(cè)脈寬,1次為278us
}
void int0() interrupt 0 //定義外部中斷0
{
static uchar i; // 聲明靜態(tài)變量(在跳出函數(shù)后在回來(lái)執(zhí)行的時(shí)候不會(huì)丟失數(shù)值)i用于把33次高電平的持續(xù)時(shí)間存入IRdata
static bit startflag; //開(kāi)始儲(chǔ)存脈寬標(biāo)志位
if(startflag) //開(kāi)始接收脈寬檢測(cè)
{
if( (IRtime < 53) && (IRtime >= 32) ) /*判斷是否是引導(dǎo)碼,底電平9000us+高4500us
這個(gè)自己可以算我以11.0592來(lái)算了NEC協(xié)議的引導(dǎo)碼低8000-10000+高4000-5000
如果已經(jīng)接收了引導(dǎo)碼那么i不會(huì)被置0就會(huì)開(kāi)始依次存入脈寬*/
i = 0; //如果是引導(dǎo)碼那么執(zhí)行i=0把他存到IRdata的第一個(gè)位
IRdata[i] = IRtime; //以T0的溢出次數(shù)來(lái)計(jì)算脈寬,把這個(gè)時(shí)間存到數(shù)組里面到后面判斷
IRtime = 0; //計(jì)數(shù)清零,下一個(gè)下降沿的時(shí)候在存入脈寬
i++; //計(jì)數(shù)脈寬存入的次數(shù)
if(i == 33) //如果存入34次 數(shù)組的下標(biāo)是從0開(kāi)始i等于33表示執(zhí)行了34次
{
IRok = 1; //那么表示脈寬檢測(cè)完畢
i = 0; //把脈寬計(jì)數(shù)清零準(zhǔn)備下次存入
}
}
else
{
IRtime = 0; //引導(dǎo)碼開(kāi)始進(jìn)入把脈寬計(jì)數(shù)清零開(kāi)始計(jì)數(shù)
startflag = 1; //開(kāi)始處理標(biāo)志位置1
}
}
void IRcordpro() //提取它的33次脈寬進(jìn)行數(shù)據(jù)解碼
{
uchar i, j, k, cord, value; /*i用于處理4個(gè)字節(jié),j用于處理一個(gè)字節(jié)中每一位,k用于33次脈寬中的哪一位
cord用于取出脈寬的時(shí)間判斷是否符合1的脈寬時(shí)間*/
k = 1; //從第一位脈寬開(kāi)始取,丟棄引導(dǎo)碼脈寬
for(i = 0; i < 4; i++)
{
for(j = 0; j < 8; j++)
{
cord = IRdata[k]; //把脈寬存入cord
if(cord > 5) //如果脈寬大于我11.0592的t0溢出率為約278us*5=1390那么判斷為1
value = value | 0x80; /*接收的時(shí)候是先接收最低位,
把最低位先放到value的最高位在和0x08按位或一下
這樣不會(huì)改變valua的其他位的數(shù)值只會(huì)讓他最高位為1*/
if(j < 7)
{
value = value >> 1; //value位左移依次接收8位數(shù)據(jù)。
}
k++; //每執(zhí)行一次脈寬位加1
}
IRcord[i] = value; //每處理完一個(gè)字節(jié)把它放入IRcord數(shù)組中。
value = 0; //清零value方便下次在存入數(shù)據(jù)
}
IRpro_ok = 1; //接收完4個(gè)字節(jié)后IRpro ok置1表示紅外解碼完成
}
void main()
{
uchar i;
P1=table[0];
init(); //執(zhí)行初始化定時(shí)器0和外部中斷0
while(1) //大循環(huán)
{
if(IRok) //判斷脈寬是否檢測(cè)完畢
{
IRcordpro();//根據(jù)脈寬解碼出4個(gè)字節(jié)的數(shù)據(jù)
IRok = 0; //重新等待脈寬檢測(cè)
if(IRpro_ok) //判斷是否解碼完畢
{
if(IRcord[2]==0x45)
{
o=0;
}
IRpro_ok = 0;
}
}
if(o==0)
{
for(i=0;i<8;i++)
{
P1=table[i];
delay(5);
}
}
}
} |
|