基于STC12系列单片机的通用红外遥控信号分析程序(一)

前言

  最近学51单片机学习到红外遥控解码与发送部分,开发板的相关教程只有NEC协议的解码,基本的解码套路是1838接收头输出管脚接单片机外部中断0,当接收到红外信号时产生下降沿触发中断,在中断函数中先延时9ms判断电平再延时4.5ms判断电平,从而跳过引导码;再分别延时560us、1690us左右不等的时间判断电平来解码“0”或“1”,直到结束;红外发送思路就是根据NEC协议及红外码值的二进制码分别控制高低电平,并延时相应的时间。但存在这么几个问题:

  1. 解码逻辑写死在中断处理函数中,不方便扩展、移植;

  2. 只能解码NEC协议的红外遥控信号,如果拿一款别的遥控器来,编码协议未知,整个程序就无能为力了;

  3. 接收到信号时实时解码,没有保存红外波形信息,不能输出波形进行分析;

  4. 只能发送NEC协议的红外遥控信号。

  恰逢外地出差,带了开发板却没带NEC的红外遥控器,手边只有空调、电视遥控器和一个带红外遥控功能的手机,于是就想利用51单片机做一个通用的红外遥控信号录波、解码、发送为一体的程序,直接录制红外波形,发送时也是直接按原波形发送,这样就做到了万能红外信号的学习与发送。同时将录制的波形数据发送到上位机进行显示、分析,这样就算拿到一款未知红外协议的遥控器,也可以做它的协议分析了。PS:本人没有示波器、逻辑分析仪,有这些装备的同学请随便看看。

红外遥控基本原理

  红外发射和接收的原理就不细说了,网上很多,也可以参见这篇文章《全面了解红外遥控(中文版)》,这是一个歪果仁写的,网友翻译,讲了基本原理,也介绍了各种常见的协议。

  需注意的是通常的介绍协议时说的表示逻辑“0”或“1”的高低电平是针对发射端的,而常用的一体化红外接收头如HS0038、VX1838等在无红外信号是输出高电平,有红外信号时输出低电平,也就是与发射端时相反的——发射端高电平发射红外线,接收端接收后产生低电平。这在解码时必须注意。

红外遥控录波硬件系统

  为了尽可能的提高录波时的分辨率,采用了1T模式的STC12C5A60S2单片机,之所以用STC12系列而没用更快的STC15系列时因为12系列DIP40封装与传统8051完全兼容,直接插51开发板上就能用。红外遥控接收头为HS0038,输出管脚接P3.2口(原理图中红外接收头只是随便找了个相近的元件做示意)。采用LCD1602做简单显示。原理图如下:

  

红外遥控录波程序实现

  本文章内只贴出关键程序,完整程序请点击下载,编译环境Keil4。

  原理:HS0038输出管脚接INT0中断,下降沿触发。当接收到红外信号后,HS0038输出管脚为低电平,进入中断处理函数,立即启动定时器0,等待红外输出管脚变为高电平,记录低电平时间;然后重置定时器0,等待红外输出管脚变为低电平,记录高电平时间;如此往复,直到某次等待超时或记录时间的数组已用完。

  录制的波形数据保存到一个unsigned char数组中,两两一组,以低电平开始(针对接收端而言),交替表示低电平、高电平的持续时间。格式为:

0x04, 0x24,    //低字节在前,实际数据为0x2404,低电平持续时间的计数值
0x84, 0x11,    //低字节在前,实际数据为0x1184,高电平持续时间的计数值
...

  该段程序不仅可以录制红外波形,还可以做简易的逻辑分析仪使用。录制波形时定时器0的计时时间为1us,所以该段程序的录波理论最小分辨率为1us,但由于中间计算过程等耗时会产生误差,所以最好用来录制电平持续时间大于10us的脉冲波形。

  录波的流程图如下:

//硬件
//@单片机          :    STC12C5A60S2
//@晶振            :    12.0MHz

void InitTimer0()    //定时器0初始化
{
    ET0 = 1;
    AUXR &= 0x7f;        //定时器时钟12T模式,1us
    TMOD &= 0xF0;        //设置定时器模式
    TMOD |= 0x01;        //设置16位定时器
    TL0 = 0x00;            //设置定时器初值
    TH0 = 0x00;            //设置定时器初值
    TF0 = 0;            //清除TF0标志
    TR0 = 0;            //暂不开启定时器0计时
    PT0 = 1;            //高优先级,必须,否则在外部中断0中就不能执行定时器0是否超时溢出
}

void Timer0Interrupt(void) interrupt 1 using 1
{
    timer0Overflow = true;    //超时溢出标志
}

void InitINT0()
{
    EX0 = 1;    //打开中断0
    IT0 = 1;    //1——下降沿触发;0——低电平触发
}

void INT0Interrupt() interrupt 0 using 2
{
    UINT8 i;
    UINT8  cH, cL;
    TR0 = 1;     //定时器0开始计数
    EX0 = 0;    //关闭外部中断0的中断响应

    usedLength = 1;    //如果没有接收到有效信号,串口发送1次共4字节数据,用来跟串口收发失败的情况区分
    for (i = 0; i < MAX_BUFFER_LENGTH / 4; i++)
    {
        while (!IR_In)
        {
            if (timer0Overflow)
            {
                usedLength = i;
                goto endfor; //65ms,超时,跳出循环
            }
        }
        TR0 = 0;
        cL = TL0;    //取定时数据
        cH = TH0;
        TL0 = 0x00;    //初始化
        TH0 = 0x00;
        timer0Overflow = false;
        TR0 = 1;     //定时器0开始计数

        waveData[4 * i + 0] = cL;
        waveData[4 * i + 1] = cH;

        while (IR_In)
        {
            if (timer0Overflow)
            {
                usedLength = i;
                goto endfor; //65ms,超时,跳出循环
            }
        }
        TR0 = 0;
        cL = TL0;    //取定时数据
        cH = TH0;
        TL0 = 0x00;    //初始化
        TH0 = 0x00;
        timer0Overflow = false;
        TR0 = 1;     //定时器0开始计数

        waveData[4 * i + 2] = cL;
        waveData[4 * i + 3] = cH;

        usedLength = i;
    }
endfor:
    TR0 = 0;    //关闭定时器0
    timer0Overflow = false;
    TL0 = 0x00;
    TH0 = 0x00;

    if (usedLength > 2)    //至少录制了一组有效数据,显示录制的数据长度
    {
        Lcd1602Clear();

        setPos(0, 0);
        writeData(‘L‘);
        writeData(‘:‘);
        writeData((usedLength + 1) * 4 / 100 + ‘0‘);
        writeData((usedLength + 1) * 4 / 10 % 10 + ‘0‘);
        writeData((usedLength + 1) * 4 % 10 + ‘0‘);
    }

    IE0 = 0;    //若接收信号过程中产生了下降沿,IE0则为1,此处需清除外部中断0的中断标志
    EX0 = 1;    //打开外部中断0的中断响应
}

  按键发送数据,同时添加了一个按键做清空缓存数组用,程序如下:

void main()
{
    UINT16 n;

    InitSys();

    while (1)
    {
        Key_Send = 1;
        if ( Key_Send != 1)
        {
            DelayX10ms(1);
            Key_Send = 1;
            if (Key_Send != 1)
            {
                for (n = 0; n < usedLength; n++)
                {
                    //将波形数据串口发送到上位机
                    UartSendByte(waveData[4 * n + 0]);
                    UartSendByte(waveData[4 * n + 1]);
                    UartSendByte(waveData[4 * n + 2]);
                    UartSendByte(waveData[4 * n + 3]);
                }

                while (!Key_Send);    //等待弹起
            }
        }

        Key_Clear = 1;
        if ( Key_Clear != 1)
        {
            DelayX10ms(1);
            Key_Clear = 1;
            if (Key_Clear != 1)
            {
                //清空波形缓存数组
                for (n = 0; n < MAX_BUFFER_LENGTH; n++)
                {
                    waveData[n] = 0;
                }
                SystemReady();
                while (!Key_Send);
            }
        }
    }
}

上位机红外波形分析

  录制完波形后,波形数据通过串口发送到上位机,得到类似下图的十六进制数据,进行数据处理后就可以进行分析解码了。

  为方便分析,我用C#简单写了个小程序,可以很方便的绘制波形,并将每帧的2字节数据直接转换为时间长度,方便对照各种红外协议分析。如下图,该段红外信号已9220us的高电平开始,紧随一个4484us的低电平,与NEC协议中“9ms高电平+4.5ms低电平”的引导码格式相符,分析其后面的电平持续时间,可知这段红外信号为NEC格式信号。

上位机程序及源码下载

时间: 2024-08-11 14:14:42

基于STC12系列单片机的通用红外遥控信号分析程序(一)的相关文章

基于短消息的远程家电红外遥控系统

通过远程广域网控制家电设备是信息家电的主要发展方向之一.由于价格低廉.覆盖面广.使用方便等原因,短消息平台已经成为远程家电控制的重要方法. 本文研究和开发了一种基于短消息的远程红外遥控系统.该系统以Java语言应用程序作为客户控制终端,以短消息作为控制信号的传输平台,以家电常用的红外遥控器作为控制设备,形成了比较完备的远程家电控制系统原型. 本文首先分析了广域网传输技术.家电控制设备.客户控制终端等三个关键技术的选型问题,并据此提出了系统设计的总体结构. 随后,本文介绍了系统的硬件设计,着重讨论

基于STM32的学习型通用红外遥控设备的设计实现(三)

3.1 红外脉宽存储及FLASH的读写 根据STM32型号的不同,FLASH容量由16K到1024K不等. FLASH模块主要由三部分组成:主存储器.信息块.闪存存储器接口寄存器.模块组织见<STM32中文参考手册>小节<2.3.3 嵌入式闪存>. 主存储器用来存放代码和数据常数,对于大容量产品,划分为256页,每页2K字节:中小容量产品每页则是1K.信息块的启动程序代码用来存储ST自带的启动程序,用于串口下载,用户选择字节一般用来配置写保护.读保护.闪存存储器接口寄存器是整个闪存

MSP430G2接收红外遥控信号

 launch pad接收红外信号经此程序处理后以不同的值保存在char red中,数码管显示出按键对应的char red的值.可由此修改程序完成遥控. 此例中红外线发射格式:9ms高电平引导码+4.5ms结果码+53.76ms逻辑编码(有效数据)区,在逻辑编码区内的串行数据,0.56ms 的低电平+0.56ms 的高电平编码为0, 0.56ms 的低电平+ 1.68ms 的高电平编码为1. //引脚:p2.3,p2.4,p1口控制数码管的扫描显示.P2.0为红外接受输入口. #include

标准红外遥控的接收程序-松瀚汇编源程序

/**************************************************** 名称: 标准红发遥控 接收程序--4BYTE 平台为: 松瀚SN8P2511 接收方式为 定时中断接收 中断定时时间为100U *****************************************************/ ;寄存器定义 STS1 DS 1 F_IRECOK EQU STS1. 0 ;接收到一帖数据 T_IRSTA DS 1 T_IRNUMPOSI DS 1

基于STC89C52的oled红外遥控闹钟

这个红外遥控主要是程序通过对按下的键的键码进行解析,并运行相应的功能代码 一次按键动作的遥控编码信息为 32 位串行二进制码.对于二进制信号“0”,一个脉冲占 1.2ms:对于二进制信号“1”,一个脉冲占 2.4ms,而每一脉冲内低电平均为 0.6ms.从起始标志到 32 位编码脉冲发完大约需80ms,此后遥控信号维持高电平.若按键未释放,则从起始标志起每隔 108ms 发出 3 个脉冲的重复标志.在 32 位的编码脉冲中,前 16 位码不随按键的不同而变化,我们称之为用户码.它是为了表示特定用

[每日电路图] 2、红外遥控电路原理设计与解析【转+解读】

          楼主说:本文主要讲一个红外遥控电路的原理及设计,第四部分是重点,用电路图说明具体过程——接收,计数,满足条件触发控制电路! from elecfans:http://www.elecfans.com/article/88/131/198/2015/20151215394306.html 一.概述: 红外遥控的发射电路是采用红外发光二极管来发出经过调制的红外光波:红外接收电路由红外接收二极管.三极管或硅光电池组成,它们将红外发射器发射的红外光转换为相应的电信号,再送后置放大器.

[原创]基于51单片机的红外遥控课程设计

[注]: 一眨眼,大学接近尾声,具有找工作需要,所以把大学做的电子设计“劣作”放上来.希望考研失意,还能赶上“好工作”的春招班车.如果大伙有什么工作推荐也可以联系我哦,因为一年考研少接触了这方面,所以难免有些生疏.但请相信我!给我机会我会很认真学的! 邮箱:[email protected] 转载请注明出处呀! 基于51单片机的红外遥控课程设计 目录 第一章 设计简介... 3 第二章 系统方案... 3 一.设计方案对比... 3 二.方案设计... 4 第三章 硬件设计... 5 一.红外遥

基于Arduino的红外遥控

1.红外接收头介绍  一.什么是红外接收头?  红外遥控器发出的信号是一连串的二进制脉冲码.为了使其在无线传输过程中免受其他红外信号的干扰,通常都是先将其调制在特定的载波频率上,然后再经红外发射二极管发射出去,而红外线接收装置则要滤除其他杂波,叧接收该特定频率的信号并将其还原成二进制脉冲码,也就是解调. 二.工作原理  内置接收管将红外发射管发射出来癿光信号转换为微弱的电信号,此信号经由IC内部放大器进行放大,然后通过自动增益控制.带通滤波.解调变.波形整形后还原为遥控器发射出的原始编码,经由接

第八篇:基于物联网/WIFI/单片机的智能插排控制系统论文、开题报告、原理图(全套毕业设计资料,绝对干货,内附下载链接)

首先打个广告:如果需要做毕设以及嵌入式项目合作,欢迎进入我们工作室:创想嵌入式设计工作室 以下时本人独立开发设计的毕设项目课题:<基于物联网/WIFI/单片机的智能插排>,现在共享出来供大家参阅,可用于做项目时借鉴,博尾附有下载链接.(内附本人联系方式,可一起交流探讨,交朋友). 针对本课题,本次共享的资料包几乎涵盖毕业设计所需的全部资料:设计方案,开题报告,程序源码,原理图,模块资料,论文,答辩PPT,模块学习资料,等等.本资料包不仅仅适用于"基于物联网/WIFI/单片机的智能插排