//STC89C52RC_雙倍速_外部晶振24MHz
#include "reg51.h"
#include "intrins.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define uchar unsigned char
#define uint unsigned int
unsigned char ir_dat_buf[4] = {0}; //紅外遙控接收碼存放位置
unsigned char mode; //紅外線接收模式緩存
sbit P32 = P3^2; //IR
void Delay1120us(void)
{
TL1 = 0xC4;
TH1 = 0xEE;
TR1 = 1;
while(!TF1);
TR1 = 0;
TF1 = 0;
}
void Delay840us(void)
{
TL1 = 0x38;
TH1 = 0xF3;
TR1 = 1;
while(!TF1);
TR1 = 0;
TF1 = 0;
}
unsigned char ir_read(void) // 數(shù)據(jù) 0: 0.56ms低電平,0.56ms高電平
{ // 數(shù)據(jù) 1: 0.56ms低電平,1.58ms高電平
unsigned char i,ir_temp = 0;
for(i = 0; i < 8; i++)
{
while(!P32); //等待0.56ms低電平結(jié)束
Delay840us(); //從高電平開始延時0.84ms
if(P32 == 1)
{
ir_temp = (ir_temp << 1) + 1; //讀到數(shù)據(jù)1
Delay1120us(); //延時等待1.68ms高電平結(jié)束
}
else
{
ir_temp = ir_temp << 1; //讀到數(shù)據(jù)0
}
}
return ir_temp;
}
void main()
{
TMOD = 0x11; //set timer0 as mode1 (16-bit)
TL0 = 0; //定時4ms
TH0 = 0;
TR0 = 1; //timer0 start running
TF0 = 1;
IT0 = 1; //set INT0 int type (1:Falling 0:Low level)
ET0 = 1; //enable timer0 interrupt
EX0 = 1; //enable INT0 interrupt
EA = 1; //open global interrupt switch
mode = 0;//紅外線接收清除
while (1)
{
switch(mode)
{
case 1: {mode=0;}break;
case 2: {mode=0;}break;
case 3: {mode=0;}break;
default: break;
}
}
}
void exint0() interrupt 0 //按鍵一次: 依次發(fā)送 引導(dǎo)碼 + 地址 + 地址取反 + 數(shù)據(jù) + 數(shù)據(jù)取反
{
static unsigned i;
EX0 = 0; //關(guān)閉外部中斷,仍可以執(zhí)行以下程序
for(i = 0; i < 10; i++) // 引導(dǎo)碼由9ms低電平及4.5ms高電平組成, 接著是低8位地址碼, 高8位地址碼
{ // 連發(fā)碼由9ms低電平及2.25ms高電平組成, 跟著是0.56ms低電平, 然后都是高電平
Delay840us();
if(P32) //檢測引導(dǎo)碼9ms是否有高電平,有則退出
{
EX0 = 1;
return;
}
}
while(!P32); //等待高電平的到來 注:盡量采用延時來檢測,不然可能會進入死循環(huán)
Delay840us();
Delay840us(); // 檢測連按; 延時2.52ms,檢測是否有低電平,有表示按鍵連按,且退出
Delay840us();
if(!P32)
{
EX0 = 1;
return;
}
while(P32); //等待4.5ms高電平結(jié)束,開始接收數(shù)據(jù)
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
ir_dat_buf[0] = ir_read();
ir_dat_buf[1] = ir_read();
ir_dat_buf[2] = ir_read();
ir_dat_buf[3] = ir_read();
EX0 = 1; //開啟外部中斷,等下次信號
}
void tm0_isr() interrupt 1 using 1
{
ET0 = 0;//禁止外部中斷,防止在接收到數(shù)據(jù)后處理過程中,再按遙控造成沖突
TL0 = 0x60; //定時4ms
TH0 = 0xC1;
if(((ir_dat_buf[0] == 0x00) && (ir_dat_buf[1] == 0xff))&&((ir_dat_buf[2])== ~(ir_dat_buf[3])))//用戶碼0x00,0xFF
{
switch(ir_dat_buf[2])
{
case 0x45: {mode=1;}break;
case 0x46: {mode=2;}break;
case 0x47: {mode=3;}break;
default: break;
}
ir_dat_buf[0]=0;//清除紅外線接收緩存
ir_dat_buf[1]=0;//清除紅外線接收緩存
ir_dat_buf[2]=0;//清除紅外線接收緩存
ir_dat_buf[3]=0;//清除紅外線接收緩存
}
ET0 = 1; //充許外部中斷,處理完數(shù)據(jù)后再打開外部中斷
} |