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

发布者:Serendipity66最新更新时间:2016-10-28 来源: eefocus关键字:状态机  SAA3010  红外遥控  接收程序 手机看文章 扫描二维码
随时随地手机看文章
//  用单片机进行红外遥控接收已经是很平常的应用了,基本上稍懂单片机就可以自己编//
//        但往往很多人编的程序要么繁琐,要么占用大量存储器、CPU资源,               //
//        而且用于现场时还可能因为受到干扰而不能正常工作                            //
//        真正试过的都会发现,要想编个真正好用的接收程序不是那么简单的              //

//        其实,所有遥控芯片的编码都是比较简单的(有限的状态),只要仔细分析它的编码//
//        我们完全可以用状态机的方式来处理各种可能的情况,甚至从被干扰的杂乱波形中找出正确的编码//
//        下面是基于状态机的SAA3010红外遥控接收程序示例:                         //
//--------------------------------------------------------------------------//
//                                                                          //
//                    (c) Copyright 2001-2003 xuwenjun                     //
//                            All Rights Reserved                           //
//                                    V1.00                                 //
//--------------------------------------------------------------------------//
//标 题: SAA3010遥控芯片接收程序                                           //
//文件名: ir_3010.c                                                         //
//版 本: V1.00                                                             //                                            //
//描 述: 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);
        }
}
*/

关键字:状态机  SAA3010  红外遥控  接收程序 引用地址:基于状态机的SAA3010红外遥控接收程序

上一篇:AT45DB041读写程序
下一篇:TLC1549数据采集

推荐阅读最新更新时间:2024-03-16 15:17

状态机思路在单片机程序设计中的应用
状态机的概念 状态机是软件编程中的一个重要概念。比这个概念更重要的是对它的灵活应用。在一个思路清晰而且高效的程序中,必然有状态机的身影浮现。 比如说一个按键命令解析程序,就可以被看做状态机:本来在A状态下,触发一个按键后切换到了B状态;再触发另一个键后切换到C状态,或者返回到A状态。这就是最简单的按键状态机例子。实际的按键解析程序会比这更复杂些,但这不影响我们对状态机的认识。 进一步看,击键动作本身也可以看做一个状态机。一个细小的击键动作包含了:释放、抖动、闭合、抖动和重新释放等状态。 同样,一个串行通信的时序(不管它是遵循何种协议,标准串口也好、I2C也好;也不管它是有线的、还是红外的、无线的)也
[单片机]
基于单片机的红外遥控信号自学习及还原新方法
1概述 随着远程教育体系的不断发展和日趋完善,多媒体教学手段在各级各类学校都得到了广泛应用。近年来,我们在进行多媒体教学系统的开发和研制过程中,经常遇到多种用于教学中的红外遥控设备,如:数字投影机、DVD、VCD、录像机、电视机等,由于各种设备都自带遥控器,而且不同的设备所遵循的红外遥控规程也不尽相同,操纵这些设备得使用多种遥控器,给使用者带来了诸多不便。我们采用集中控制各设备的方式如图(1)所示解决了该问题。集中控制各设备的方法是首先对各设备的红外遥控信号进行识别并存储(自学习),然后在需要时进行还原。图(1)中由PC或集中控制器发送设备号及控制命令号至红外遥控信号自学习及还原电路,再由自学习及还原电路恢复对应的红外遥控信号,
[单片机]
基于单片机的<font color='red'>红外遥控</font>信号自学习及还原新方法
单片机红外遥控门禁实现
     随着楼宇办公现代化、智能化的推进,靠人工有线电话预约、信息咨询和人员接待等已经不能适应办公信息化建设的需求。针对上述需求,笔者设计一种基于 单片机 控制的 红外遥控 办公语音提醒系统。当有与室内办公人员面谈需求时,只需按键遥控驱动该人员的编码信号,当该人员的红外接收模块解码接收到红外发射模块的编码信号后, 单片机 可驱动相应人员的语音芯片工作,同时该人员根据语音提醒按键驱动回送无线信号,可给室外人员提供相应提醒功能。此系统结构简单、编程方便、稳定可靠,在实际使用中效果良好。    系统总体框架   本系统由门口播报和办公桌播报等两大部分组成,由于一个红外发射模块控制多台接收模块,所以接收控制器的个数随办公对象的多少而
[嵌入式]
如何使用STATECAD进行多状态机设计实例分析
随着微电子技术的迅速发展,人们对数字系统的需求也在提高。不仅要有完善的功能,而且对速度也提出了很高的要求。对于大部分数字系统,都可以划分为控制单元和数据单元两个组成部分。通常,控制单元的主体是一个有限状态机 ,它接收外部信号以及数据单元产生的状态信息,产生控制信号序列。有限状态机设计的关键是如何把一个实际的时序逻辑关系抽象成一个时序逻辑函数,传统的电路图输入法通过直接设计寄存器组来实现各个状态之间的转换, 而用硬件描述语言来描述有限状态机, 往往是通过充分发挥硬件描述语言的抽象建模能力,通过对系统在系统级或寄存器传输级进行描述来建立有限状态机。EDA 工具的快速发展,使通过CAD快速设计有限状态机自动化成为可能。   传统上在系
[模拟电子]
如何使用STATECAD进行多<font color='red'>状态机</font>设计实例分析
SAA3010红外解码(C51)
/******************************************************************************************** * 功 能:红外解码。 * 硬件条件:1.CPU型号:AT89S52 * 2.晶振:12.000MHz * 3.用跳线帽短接P2.3__SI2 * 用跳线帽短接P2.2__RCK2 * 用跳线帽短接P2.1__SCK2 * 4.用跳线帽短接HW-IRQ__P3.2 * 5.欲完成本实验,还需另行准备一个遥控器,型号为SAA-3010T。
[单片机]
基于89C52与DT9122D红外遥控用数码管显示
本实验是89C52与DT9122D红外遥控的键值显示在数码管上,希望对朋友们有帮助,程序如下: #include reg52.h #include intrins.h typedef unsigned int uint; typedef unsigned char uchar; uchar code smg_tab ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//数码管段码0~F sbit IRINPUT=P3^2;//红外线接收头端口 uchar IR_Input_Buffer ={0x00,0x
[单片机]
MSP430G2553 状态机建模
msp430g2553快把我搞死了,暑假开始接触到单片机,现在才开始有一个大致的了解。这几天研究那个状态机建模,可能是好久都没有接触到c语言了吧。。。用起来不知道多生疏,废话不说把书上的例程搬过来,发现还是有很多的问题啊。 程序要求是短按p1.3的话,出现p1.0取反,长按p1.3的话,p1.6取反,下面是程序: #include msp430g2553.h #define IDLE 0 #define SHORT 1 #define LONG 2 #define COUNTER_THRESHOLD 50 unsigned char key_dect; unsigned char WDT_Counter=0; void GPIO_
[单片机]
SDRAM控制器的设备与VHDL实现
在高速实时或者非实时信号处理系统当中,使用大容量存储器实现数据缓存是一个必不可少的环节,也是系统实现中的重点和难点之一。SDRAM(同步动态随机访问存储器)具有价格低廉、密度高、数据读写速度快的优点,从而成为数据缓存的首选存储介制裁。但是SDRAM存储体结构与RAM有较大差异,其控制时序和机制也较复杂,限制了SDRAM的使用。目前,虽然一些能家长微处理器提供了和SDRAM的透明接口,但其可扩展性和灵活性不够,难以满足现实系统的要求,限制了SDRAM的使用。 在详细阐读SDRAM数据文档的前提下,参考ALTERA公司的IP core,利用可编程器件(CPLD,FPGA)设计了一种通用的SDRAM控制器。它具有很高的灵活性,可以方便
[缓冲存储]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved