/**************************************************************
* 文件名:Infrared.c *
* 伟杰龙电子成就工程师之路 *
* 论坛:http://bbs.weijielong.com *
* 网站:http://www.weijielong.com *
* 名称:红外线遥控解码实验 *
* 说明:数码管显示遥控地址和数据 *
**************************************************************/
#include <reg52.h>
#include "../Inc/Common.h"
#include "../Inc/CH451.h"
uchar DisplayData[8]={0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10};//数码管各位要显示的数据
//6种接收状态
#define IR_Idle 0//空闲
#define IR_WaitStart 1//接收引导代码
#define IR_GetAddress 2//接收地址
#define IR_GetAddressInv 3//接收地址反码
#define IR_GetData 4//接收数据
#define IR_GetDataInv 5//接收数据反码
#define ms_168 0x060D
#define ms_9 0x2067
#define ms_125 0x2D00
#define ms_15 0x3600
uchar IR_State=IR_Idle;//接收状态变量,初值为空闲
uchar IR_Ready=0;//数据接收完标志
uchar IR_Repeat=0;//连发标志
uchar IR_Data[4]={0,0,0,0};//接收到的4字节数据
uchar Tmp;
uint IRtimer=0;
//外部中断1中断程序
void INT1_Int() interrupt 2{
uint Count;
TR1=0;
Count=TH1*256+TL1;//读取计数值
TH1=0;
TL1=0;
TR1=1;//定时器1重新开始计数
switch(IR_State){
case IR_Idle:{
IR_State=IR_WaitStart;
IRtimer=11;//解码超时
break;
}
case IR_WaitStart:{
if((Count>ms_125)&&(Count<ms_15)){//接收到引导码
IR_Data[0]=0;
IR_Data[1]=0;
IR_Data[2]=0;
IR_Data[3]=0;
Tmp=1;
IR_Repeat=0;
IR_State=IR_GetAddress;
}else if((Count>ms_9)&&(Count<ms_125)){//接收连发代码
IR_Repeat=1;
IR_State=IR_Idle;
}else IR_State=IR_Idle;
break;
}
case IR_GetAddress:{
if(Count>ms_168){//接收到1
IR_Data[0]|=Tmp;
}
Tmp<<=1;
if(!Tmp){
IR_State=IR_GetAddressInv;
Tmp=1;
}
break;
}
case IR_GetAddressInv:{
if(Count>ms_168){//接收到1
IR_Data[1]|=Tmp;
}
Tmp<<=1;
if(!Tmp){
IR_State=IR_GetData;
Tmp=1;
}
break;
}
case IR_GetData:{
if(Count>ms_168){//接收到1
IR_Data[2]|=Tmp;
}
Tmp<<=1;
if(!Tmp){
IR_State=IR_GetDataInv;
Tmp=1;
}
break;
}
case IR_GetDataInv:{
if(Count>ms_168){//接收到1
IR_Data[3]|=Tmp;
}
Tmp<<=1;
if(!Tmp){
if(((IR_Data[0]^IR_Data[1])==0xFF)&&((IR_Data[2]^IR_Data[3])==0xFF)) IR_Ready=1;//校验数据
IR_State=IR_Idle;
}
break;
}
default:{
IR_State=IR_Idle;
break;
}
}
}
//定时器初始化
void InitTimer(){
TMOD=0x11;//方式1
EX1=1;//开外部中断1
IT1=1;//下降沿触发
ET0=1;//允许T0中断
TH0=0xDC;//定时器初值10ms
TL0=0x00;
TR0=1;//启动T0
}
//定时器0中断
void Time0Int() interrupt 1{
if(IRtimer) IRtimer--;
else IR_State=IR_Idle;//解码超时
}
void main(){
uchar i;
InitTimer();//定时器初始化
CH451_Init();//初始化CH451
for(i=0;i<8;i++) CH451_DisplayDig(7-i,DisplayData[i],0);//显示数据
EA=1;//打开中断
while(1){
if(IR_Ready==1){//计算要显示的每位数字
IR_Ready=0;
DisplayData[7]=IR_Data[2]%16;//数码管后2位显示数据
DisplayData[6]=IR_Data[2]/16;
DisplayData[1]=IR_Data[0]%16;//数码管前2位显示地址
DisplayData[0]=IR_Data[0]/16;
}
for(i=0;i<8;i++) CH451_DisplayDig(7-i,DisplayData[i],0);//显示新的数据
}
}