使用NEC协议
#include <reg52.h>
typedef unsigned char INT8U;//使用typedef给已有的数据类型取别名
typedef unsigned char uchar;
typedef unsigned char u8;
typedef unsigned int INT16U;
typedef unsigned int uint;
typedef unsigned int u16;
uchar IRtime; //储存检测红外高低电平持续时间
uchar IR_Decord[4]; //储存解码后的4个字节数据
uchar IRdata[33]; //包含起始码在内的33位数据
bit IRcord_ok; //解码后四个字节数据接收完成标志
bit IRok; //33位数据接收完成标志
/*初始化定时器0,外部中断0,串口*/
void Init()
{
TMOD|=0x02;//设置定时器0工作模式2,8位自动重装
TL0 = 0;
TH0 = 0;//定时器溢出一次时间位256个机械周期
EA = 1; //开总中断
ET0 = 1;//开定时器0中断
TR0 = 1;//启动定时器0
IT0 = 1;//设置外部中断0下降沿触发方式
EX0 = 1;//开外部中断0
TMOD |= 0x20;//设置定时器1工作模式2,8位自动重装
TL1 = TH1 = 0xfd;//比特率为9600
SM0 = 0; SM1 = 1;//设置串口工作模式1,8位异步收发
TR1 = 1;
}
/*定时器0中断,每中断一次需要256*1.085us = 277.76us*/
void Timer0() interrupt 1
{
IRtime++;//277.76us
}
/*外部中断0,存入33次脉宽*/
void Timer0_Exterior() interrupt 0
{
static uchar i;
static bit StartFlag;//开始储存脉宽标志位
if(StartFlag)
{
/*判断引导码,如果是引导码则从起始码开始存*/
if((IRtime<53)&&(IRtime>32 )) i = 0;
IRdata[i] = IRtime;//以T0溢出的次数来计算脉宽把这个给时间放在数组中
IRtime = 0; //清零,为下一次做准备
i++;
if(i==33)//记录完成
{
IRok = 1;//33位数据接收完成标志
i = 0;
}
}
else
{
IRtime = 0;
StartFlag = 1;
}
}
/*把提取的33次脉宽进行解码 NEC协议*/
void IRcord_pro()
{
uchar i;//用于计数处理4个字节
uchar j;//用于计数处理1个字节的8位数据
uchar k;//用于计数处理33次脉宽
k = 1;//从第一位脉宽开始处理,丢掉起始码
for(i = 0;i<4;i++)
{
for(j=0;j<8;j++)
{
/*如果脉宽大于数据0的标准的1125us,那么就判定为数据1*/
if(IRdata[k]>5) IR_Decord[i]|=0x80;
if(j<7) IR_Decord[i]>>=1;//右移7次
k++;
}
}
IRcord_ok = 1;
}
void main()
{
uchar i;
Init();
while(1)
{
if(IRok)//判断33次脉宽是否提取完成
{
IRcord_pro();//根据脉宽解码出4个字节
IRok = 0;
if(IRcord_ok)//判断解码是否完成
{
for(i=0;i<4;i++)//串口发送4个字节数据
{
SBUF = IR_Decord[i];
while(!TI);
TI = 0;
}
IRcord_ok = 0;
}
}
}
}