SAA3010红外遥控接收的C程序源代码
//? 用单片机进行红外遥控接收已经是很平常的应用了,基本上稍懂单片机就可以自己编//
//??????? 但往往很多人编的程序要么繁琐,要么占用大量存储器、CPU资源,?????????????? //
//??????? 而且用于现场时还可能因为受到干扰而不能正常工作??????????????????????????? //
//??????? 真正试过的都会发现,要想编个真正好用的接收程序不是那么简单的????????????? //
//??????? 其实,所有遥控芯片的编码都是比较简单的(有限的状态),只要仔细分析它的编码//
//??????? 我们完全可以用状态机的方式来处理各种可能的情况,甚至从被干扰的杂乱波形中找出正确的编码//
//??????? 下面是基于状态机的SAA3010红外遥控接收程序示例:???????????????????????? //
//--------------------------------------------------------------------------//
//????????????????????????????????????????????????????????????????????????? //
//??????????????????? (c) Copyright 2001-2003 xuwenjun???????????????????? //
//??????????????????????????? All Rights Reserved?????????????????????????? //
//??????????????????????????????????? V1.00???????????????????????????????? //
//--------------------------------------------------------------------------//
//标 题: SAA3010遥控芯片接收程序?????????????????????????????????????????? //
//文件名: ir_3010.c???????????????????????????????????????????????????????? //
//版 本: V1.00???????????????????????????????????????????????????????????? //
//修改人: xuwenjun???????????????????????? E-mail:xuwenjun@21cn.com???????? //
//日 期: 03-06-14????????????????????????????????????????????????????????? //
//描 述: SAA3010遥控芯片接收程序?????????????????????????????????????????? //
//--------------------------------------------------------------------------//
//老版本: 无???????????????????????????? 老版本文件名:????????????????????? //
//创建人: xuwenjun???????????????????????? E-mail:xuwenjun@21cn.com???????? //
//日 期: 03-06-14????????????????????????????????????????????????????????? //
//描 述: SAA3010遥控芯片接收程序?????????????????????????????????????????? //
//??????? 当ykok=1时,ykcode中的数据就是接收到的遥控码(14位的最后8位)??????? //
//--------------------------------------------------------------------------//
//占用以下资源:???????????????????????????????????????????????????????????? //
//??????? 1. 遥控使用外部中断0,接P3.2口???????????????????????????????????? //
//??????? 2. 遥控使用定时计数器1??????????????????????????????????????????? //
//??????? 3. 5.1字节data RAM??????????????????????????????????????????????? //
//??????? 4. 293字节 code ROM?????????????????????????????????????????????? //
//--------------------------------------------------------------------------//
//声 明:?????????????????????????????????????????????????????????????????? //
//??????? 以下代码仅免费提供给学习用途,但引用或修改后必须在文件中声明出处. //
//??????? 如用于商业用途请与作者联系.??? E-mail:xuwenjun@21cn.com?????????? //
//??????? 有问题请mailto xuwenjun@21cn.com?? 欢迎与我交流!????????????????? //
//--------------------------------------------------------------------------//
#i nclude
#define uchar unsigned char
//? SAA3010存储定义
uchar ykcode;??????????????????????????????????????????????????????? //遥控码(14位的最后8位)
bit ykok;???????????????????????????????????????????????????????? //遥控数据有效标志
uchar ykbnum;???????????????????????????????????????????????? //遥控已接收位数
uchar ykbtc;??????????????????????????????????????????????? //遥控中断时 ykbtc=TH1
uchar ykdelay;??????????????????????????????????????????????? //遥控延时接收
bdata uchar ykcodetemp;??????????????????????????????????????? //遥控临时码
sbit ykcodetemp0=ykcodetemp^0;
//? SAA3010端口定义
//sbit YKIO=P3^3;??????????????????????????????????????? //遥控使用外部中断0,接P3.2口
//? SAA3010函数原型: 公用函数
void YkInit(void);??????????????????????????????????????? //遥控接收初始化
unsigned char YkGetcode(void);??????????????? //返回遥控码
bit YkTest(void);??????????????????????????????????????? //检查有无遥控信号
/*
//? SAA3010函数原型: 公用函数
extern void YkInit(void);??????????????????????????????????????????????? //遥控接收初始化
extern unsigned char YkGetcode(void);??????????????????????? //返回遥控码
extern bit YkTest(void);??????????????????????????????????????????????? //检查有无遥控信号
*/
/*
??????? //? 外部引用四位LED显示模块? //
extern unsigned char code tab_duam[];??????????????????????? //位映射
extern void led_send(unsigned char d);??????????????????????? //发送子程序
extern void led_cls(void);??????????????????????????????????????????????? //清除显示
extern void led_show(unsigned int n);??????????????????????? //显示数字子程序
extern void led_showhh(unsigned int n);??????????????????????? //16进制显示数字子程序
extern void led_test(void);??????????????????????????????????????????????? //4LED测试函数
extern void led_delay(unsigned char? ms);??????????????? //延迟函数
*/
//? SAA3010函数内容
void YkInit(void)??????????????????????????????????????? //遥控接收初始化
{
??????? TMOD=0x11;?????????????????????????????????????????? //TMOD T0,T1均选用方式1(16位定时)
??????? SCON=0x00;
??????? TH1=0;
??????? TL1=0;
??????? IE|=0x89;?????????????????????????????????????????? //SETB??????? EX0 0x1? 外部中断 0 允许
??????????????????????????????????????????????????????????????????????? //SETB??????? ET0 0x8? 定时器 1 中断允许
????????????????????????????????????????????????????????????????????????? //SETB??????? EA? 0x80 开中断
??????? IP|=0x01;?????????????????????????????????????????? //SETB? INT0 中断优先
??????? TCON |= 0x41;??????????????????????????????????? //TCON? EX0下降沿触发,启动T1 //
??????? ykbnum=0;
??????? ykcodetemp=0;
??????? ykdelay=0;
}
unsigned char YkGetcode(void)??????????????????????? //返回遥控码
{
??????? return(ykcode);
}
bit YkTest(void)??????????????????????????????????????? //检查有无遥控信号
{
??????? return(ykok);
}
void intx0() interrupt 0 using 2??????? //遥控使用外部中断0,接P3.2口
{
??????? ykbtc=TH1;TH1=0;TL1=0;TR1=1;ET1=1;
??????? switch(ykbnum)
??????? {
??????????????? case(0):
??????????????????????? ykbnum=1;
??????????????????????? break;
??????????????? case(1):
??????????????????????? if(ykbtc==6)ykbnum=2;
??????????????????????? else ykbnum=0;
??????????????????????? break;
??????????????? case(2):
??????????????????????? if(ykbtc==6||ykbtc==9)ykbnum=3;
??????????????????????? else ykbnum=0;
??????????????????????? break;
??????????????? case(3):
??????????????????????? if(ykbtc==9||ykbtc==6){ykbnum=4;}
??????????????????????? else ykbnum=0;
??????????????????????? break;
??????????????? default:
??????????????????????? if(ykbnum<7)if(ykbtc==6)ykbnum++;
??????????????????????????????????????????????? else ykbnum=0;
??????????????????????? else
??????????????????????? {
??????????????????????????????? if(ykbtc==6){if(ykcodetemp0)ykcodetemp=ykcodetemp*2+1;
???????????????????????????????????????????????????????? else ykcodetemp=ykcodetemp*2;
???????????????????????????????????????????????????????? ykbnum++;
??????????????????????????????????????????????????????? }
??????????????????????????????? else if(ykbtc==9){??????? if(ykcodetemp0){ykbnum++;ykcodetemp=ykcodetemp*2;}?
??????????????????????????????????????????????????????????????????????? else {ykbnum+=2;ykcodetemp=ykcodetemp*2;ykcodetemp=ykcodetemp*2+1;}
???????????????????????????????????????????????????????????????? }
???????????????????????????????????????? else if(ykbtc>11&&ykbtc<15)
??????????????????????????????????????????????????????? {ykbnum+=2;ykcodetemp=ykcodetemp*2;ykcodetemp=ykcodetemp*2+1;}
??????????????????????????????????????????????????????? else if(ykbtc>30){EX0=1;}
???????????????????????????????????????????????????????????????? else ykbnum=0;???????????????
??????????????????????? }
??????? }
}?
void intt1() interrupt 3 using 3??????? //遥控使用定时计数器1
{
??????? if(ykdelay){ykdelay--;EX0=0;}??????? //ykdelay不为0暂停接收
??????? else
??????? {
??????????????? if(ykbnum==13)??????????????????????????????? //遥控码最后一位为0,补0
??????????????? {
??????????????????????? ykcode=ykcodetemp*=2;
??????????????????????? ykdelay=3;
??????????????????????? EX0=0;??????????????????????????????????????? //暂停接收
??????????????????????? ykok=1;??????????????????????????????????????? //遥控数据有效
??????????????? }
??????????????? else if(ykbnum==14)??????????????????????? //遥控码最后一位为1,不用补
???????????????????????? {
??????????????????????????????? ykcode=ykcodetemp;
??????????????????????????????? ykdelay=3;
??????????????????????????????? EX0=0;??????????????????????????????? //暂停接收
??????????????????????????????? ykok=1;??????????????????????????????? //遥控数据有效
???????????????????????? }
???????????????????????? else EX0=1;??????????????????????? //ykbnum不为13,14接收无效,继续接收
??????????????? ykbnum=0;
??????????????? ykcodetemp=0;
??????? }
}
/*
//? SAA3010测试主函数内容
main()
{
??????? YkInit();
??????? led_test();??????????????????????????????????????? //4LED测试函数
??????? for(;1;)??????????????????????????????????????????????? //主程序
??????? {
??????????????? if (YkTest())
??????????????????????? led_showhh(YkGetcode());
??????????????? led_delay(10);
??????? }
}
评论