/****************************************/
/*杭州电子&计算机工作室 */
/*http://www.hificat.com */
/*SAA3010红外线遥控解码实验 */
/*目标器件:AT89S51 */
/*晶振:11.0592MHZ */
/*编译环境:Keil 7.50A */
/****************************************/
#define SAA3010_GLOBALS
#include <reg51.h>
#include "SAA3010.h"
#include "main.h"
//===========================================================================================================
// 该函数的作用是每调用一次就在temp1-4组成的32bit长度的最低位上移入
// 一个0或者1,数据由bitdata确定
void SAA3010_cycle_data(unsigned char bitdata)
{
temp4=temp4<<1;
if((temp3&0x80)==1) temp4=temp4|0x01;
else temp4=temp4&0xfe;
temp3=temp3<<1;
if((temp2&0x80)==1) temp3=temp3|0x01;
else temp3=temp3&0xfe;
temp2=temp2<<1;
if((temp1&0x80)==1) temp2=temp2|0x01;
else temp2=temp2&0xfe;
temp1=temp1<<1;
if(bitdata==1) temp1=temp1|0x01;
else temp1=temp1&0xfe;
}
//===========================================================================================================
// 解码出错返回1,对则返回0
unsigned char SAA3010_decode(void)
{
//-----------------------------------------------------------------------------------------------------------
unsigned char count=0;
TR1=1; // 启动计时
while(1)
{
while(ir_receive==0); // 等待电平变高,不需要超时监测
TR1=0; // 高电平(对发射电路而言)测试结束
high_level_time=TH1*256+TL1; // 记录高电平的数据
//-----------------------------------------------------------------------------------------------------------
TH1=0; TL1=0; TR1=1; // 启动对低电平的测试
//-----------------------------------------------------------------------------------------------------------
// 处理低电平
if((high_level_time<750)||(high_level_time>1800)) return 1; // 不是合格的电平
if((high_level_time>750)&&(high_level_time<1000)){SAA3010_cycle_data(0);count+=1;} // 移入一个0
if((high_level_time>1500)&&(high_level_time<1800)) {SAA3010_cycle_data(0);SAA3010_cycle_data(0);count+=2;} // 移入两个0
while(ir_receive==1) // 等待电平变低
{
if(TH1>0x08) break; // 高电平超时,正常情况下是测试结束,异常时则是出错
}
TR1=0; // 低电平(对发射电路而言)测试结束
if(TH1>0x08) {break;}
low_level_time=TH1*256+TL1; // 保存低电平的数据
TH1=0; TL1=0; TR1=1; // 为增加计时的准确性,数据的处理都是在计时过程里
//-----------------------------------------------------------------------------------------------------------
// 处理高电平
if((low_level_time<750)||(low_level_time>1800)) return 1; // 不是合格的电平
if((low_level_time>750)&&(low_level_time<1000)) {SAA3010_cycle_data(1); count+=1;} // 移入一个0
if((low_level_time>1500)&&(low_level_time<1800)) {SAA3010_cycle_data(1); SAA3010_cycle_data(1);count+=2;} // 移入两个0
}
if(count==26) {SAA3010_cycle_data(1); count++;}
if(count!=27) return 1;
led=0;
// 提取按健信息
key_code=0;
if((temp1>>1)&0x01) key_code=key_code|0x01;
else key_code=key_code&0xfe;
if((temp1>>3)&0x01) key_code=key_code|0x02;
else key_code=key_code&0xfd;
if((temp1>>5)&0x01) key_code=key_code|0x04;
else key_code=key_code&0xfb;
if((temp1>>7)&0x01) key_code=key_code|0x08;
else key_code=key_code&0xf7;
if((temp2>>1)&0x01) key_code=key_code|0x10;
else key_code=key_code&0xef;
if((temp2>>3)&0x01) key_code=key_code|0x20;
else key_code=key_code&0xdf;
// 提取系统信息
sys_code=0;
if((temp2>>5)&0x01) sys_code=sys_code|0x01;
else sys_code=sys_code&0xfe;
if((temp2>>7)&0x01) sys_code=sys_code|0x02;
else sys_code=sys_code&0xfd;
if((temp3>>1)&0x01) sys_code=sys_code|0x04;
else sys_code=sys_code&0xfb;
if((temp3>>3)&0x01) sys_code=sys_code|0x08;
else sys_code=sys_code&0xf7;
if((temp3>>5)&0x01) sys_code=sys_code|0x10;
else sys_code=sys_code&0xef;
if((temp3>>7)&0x01) sys_code=sys_code|0x20;
else sys_code=sys_code&0xdf;
data_available=1;
return 0;
}
//===========================================================================================================