好久没折腾过单片机的东西了,最近在折腾着自己DIY一个APE播放机,要用到红外控制,复习了下51的东西,用AT89C2051写了个红外解码程序,丢在这里吧,供以后参考;
#define ST_FREE 0X01
#define ST_TRIGGED 0x02
#define ST_CODE 0x03
#define LEN_HIGH 0x15//0.1*16=1.60ms 0.56+1.68=2.24ms
#define LEN_FINISH 300//20ms/0.1=200
#define IR_COUNT_END 0x20//16地址+8位数据+8位数据反码
void init_int(); // 中断初始化函数,是能EX0和ET0
void init_timer_com(); // timer和UART初始化函数
void send_com(unsigned char data_send);//串口数据发送函数
void int_enable(unsigned char flag); //中断开关函数
unsigned char get_ir_rawcode(); //取得原始红外码
#endif
int m_sys_tick,m_tick_cur; //系统时钟TICK和当前TICK
unsigned char s_ir; //系统状态机
unsigned char ir_mask[16],count_ir; //可以容纳最多128位数据
//以上变量都需要在初始化时做清零
/*
× | ST_FREE | ST_TRIGGED | ST_FREE
*
* |-------------|-引导码-|-地址码-|-数据码-|-停止码-|-----------------------|
*
*/
void func_intex0() interrupt 0
{
unsigned char i,j;
if(s_ir==ST_FREE)//引导码,进入TRIG状态,建立好同步时机,不做记录,后面码字刚好4个字节
{
s_ir=ST_TRIGGED;
m_tick_cur=m_sys_tick;
}
else if(s_ir==ST_TRIGGED)
{
s_ir=ST_CODE;
m_tick_cur=m_sys_tick;
count_ir=0;
}
else
{
i=count_ir/8;
j=count_ir%8;
if((m_sys_tick-m_tick_cur)>LEN_HIGH)
{
ir_mask[i]|=0x01<<j;
}
else
{
ir_mask[i]&=~(0x01<<j);
}
m_tick_cur=m_sys_tick;
count_ir++;
}
}
void func_intt0() interrupt 1
{
m_sys_tick++;
}
void main()
{
unsigned char data_ir;
s_ir=ST_FREE;
m_sys_tick=m_tick_cur=0;
count_ir=0;
P3=0XFF;
P1=0XFF;
init_int();
init_timer_com();
int_enable(1);
while(1)
{
if((s_ir==ST_CODE)&&(m_sys_tick-m_tick_cur)>LEN_FINISH)//已经超过20MS没有收到红外信号
{
if(count_ir>=IR_COUNT_END)//如果是完整的码字,处理并发送
{
data_ir=get_ir_rawcode();
send_com(data_ir);
P1=data_ir;
}
else//如果非完整码字或重复码,直接丢弃,进入FREE状
{
send_com(0xff);
}
s_ir=ST_FREE; // 一段码已经接受完成,设置为空闲状态
}
}
}
void init_int()
{
IE=0;//先清整个寄存器,关闭总中断
IP=0;//关闭优先级管理
IT0=1;//外部中断0下降沿触发
ET0=1;//定时器0开中断
EX0=1;//外部中断0开中断
}
void int_enable(unsigned char flag)
{
if(flag)
{
EA=1;
}
else
{
EA=0;
}
}
void init_timer_com()
{
TMOD=0x22;//都为模式2 定时,自动加载初始值
TH0=TL0=0X9c;//100us
TH1=TL1=0xE6;//1200 band/s
SCON=0X00;//先清零
PCON=0X00;//不使用倍速功能
SM0=0;
SM1=1;//使用模式1,8位异步收发,不允许接受
TR0=TR1=1;//打开定时器,初始化完成
}
void send_com(unsigned char data_send)
{
SBUF=data_send;
while(!TI);
TI=0;
}
unsigned char get_ir_rawcode()
{
if(ir_mask[2]==~ir_mask[3])
{
return ir_mask[2];
}
else
{
return 0xff;
}
}