IC资料查询:
武汉力源搜索:
  资料类型
输入器件型号关键字 :

资料 货源 价格
公告
载入中...

导航
载入中...

最新更新
载入中...

新回复
载入中...

留言
载入中...

blog信息
载入中...

链接

站长个人入口













  欢迎光临文君阁!


匠人的百宝箱


hotpower的水潭


AVR猎手的地盘


电脑圈圈的家当

友情链接

友情链接

友情链接

友情链接

友情链接

友情链接

友情链接

友情链接

友情链接

友情链接

友情链接

友情链接

友情链接

友情链接

友情链接

友情链接

友情链接

友情链接

基于状态机的SAA3010红外遥控接收程序

 //  用单片机进行红外遥控接收已经是很平常的应用了,基本上稍懂单片机就可以自己编//
//        但往往很多人编的程序要么繁琐,要么占用大量存储器、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 <reg52.h>
#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);
        }
}
*/




//太晚了,详细解释另文畅叙,大家可以先研究下哦 

 //本程序由xwj设计的UltraEdit脚本加亮显示,如需要脚本访问我的Blog //或发送邮件至:xwjfile@21cn.com

xwj 发表于 2006-3-10 0:22:00

Re:基于状态机的SAA3010红外遥控接收程序
good but ....(游客)"太晚了,详细解释另文畅叙"
我在博主的网站上并没有看到“详细解释另文畅叙”呀,
事实上你的程序地方都有问题,
望博主予以详细说明
good but ....(游客)发表评论于2007-5-19 11:50:00
返回首页     个人主页 | 引用 | 返回 | 删除 | 回复

回复:基于状态机的SAA3010红外遥控接收程序
参考(游客)

不知道晶振是多少,我用的11.0592的,

运行楼主的程序所有奇数遥控码都有可能出错,得出的值*2了

0x01=>0x02

......

0x1d=>0x3a

参考(游客)发表评论于2006-4-1 13:08:00
返回首页     个人主页 | 引用 | 返回 | 删除 | 回复

发表评论:
载入中...