红外发射管有2个管脚,发送的是经过38KHz时钟调制过的信号。例如下图使用PWM产生一个等占空时钟信号用于调制。

接收管收下来的信号已经经过了解调,可以直接连接系统的外部中断脚。

下面通过逻辑分析仪来实际测量一下。

随便找了个红外遥控器,测量power键按下后的波形。首先是信号发送侧。

可以看到,0秒开始是一个按键动作,0.11秒后的那个波形是一个repeat,展开:

把波形重叠的部分展开,就可以看到这个38KHz的调制时钟

如果持续按下遥控器上的按键,那么就会发送连续的repeat信号,发送的间隔也基本满足协议上指出的110ms

下面是接收侧

可以看到信号被解调了,也就是说重叠的部分变成了低电平。

最后通过编写协议分析插件的方式,来描述如何通过程序来理解上面的波形。

我使用的逻辑分析软件是 Saleae Logic 1.1.15 编译环境是Microsoft Visual Studio 2008,编译时需要SaleaeAnalyzerSdk-1.1.14。完整的代码从这里下载。

分析的方法是测量两个信号下降沿之间的时间长度,这里先定义一些时间参数。

/* Timing define , unit : ms*/
#defineSTART_LOW_TIMING
#defineSTART_HIGH_TIMING
#defineREPEAT_HIGH_TIMING
#defineLOGIC_ONE_TIMING         (*)
#defineLOGIC_ZERO_TIMING        (*)
#defineDATA_LOW_TIMING          (*) 

从逻辑分析仪测量的结果,可以发现发射器给出的信号并不是非常的精确,所以我们需要定义误差范围。

/* Timing Margin , unit : ms*/

#definedelta                     

在下面代码里,通过API函数AdvanceToNextEdge来获取下一个信号发生变化的采样点,如果对应的采样点是低电平,则表示下跳沿,这时和前一个下跳沿采样点的时间做差,按照采样频率换算成时间间隔。再根据上面定义的时间常量来判断这是一个START标记、REPEAT标记、逻辑1、逻辑0还是无效的信号。对于逻辑1和0的情况,需要通过移位来整理成32bits的有效数据,这里要特别注意协议里规定,先发送的是LSB,后发送的MSB。

void IRNECAnalyzer::WorkerThread()
{
    U64    per_sample = ;
    U64    cur_sample = ;
    U64    starting_sample = ;
    U64    differ = ;
    char action = state_down;
    U8    fail = ;
    U64    data = ;
    U32    code = ;
    U8    count = ;
    U8    data_f = ;

    mResults.reset(new IRNECAnalyzerResults( this, mSettings.get() ) );
    SetAnalyzerResults(mResults.get() );
    mResults->AddChannelBubblesWillAppearOn(mSettings->mInputChannel );
    mSampleRateHz= GetSampleRate();
    mSerial= GetAnalyzerChannelData( mSettings->mInputChannel );

    if( mSerial->GetBitState() == BIT_LOW )
        mSerial->AdvanceToNextEdge();

    for(;;){
        mSerial->AdvanceToNextEdge();
        cur_sample= mSerial->GetSampleNumber();

        //只处理时钟的下跳沿

        if(mSerial->GetBitState() == BIT_LOW){
            differ= (cur_sample - per_sample)*/mSampleRateHz;

            //判断是否是REPEAT信号
            )<differ)&&((differ)<(START_LOW_TIMING+REPEAT_HIGH_TIMING+delta*))){
                action=state_repeat;
                fail=;
            })<differ)&&((differ)<(START_LOW_TIMING+START_HIGH_TIMING+delta*))){
            //判断是否是START信号
                action=state_start;
                fail=;
            }else
            )<differ)&&((differ)<(LOGIC_ONE_TIMING+DATA_LOW_TIMING+delta*))){
            //判断是否是逻辑1
                action=state_data;
                data_f=;
                fail=;
            })<differ)&&((differ)<(LOGIC_ZERO_TIMING+DATA_LOW_TIMING+delta*))){
                //判断是否是逻辑0
                action=state_data;

                data_f=;

                fail=;

            }else{
                  //否则为错误信号
                fail=;
            }

            ){
                switch (action){
                    case state_start:
                        code= ;
                        count= ;
                        starting_sample= cur_sample;
                        AddFrame(per_sample,cur_sample, , FStart);
                        break;

                    case state_data:
                        data_f= data_f << count;
                        code= code | data_f;
                        count++;
                        ){
                            count= ;
                            AddFrame(starting_sample,cur_sample, code, FData);
                            code= ;
                            starting_sample= cur_sample;
                        }
                        break;

                    case state_repeat:
                        AddFrame(per_sample,cur_sample, data, FRepeat);
                        break;

                    default:
                        break;
                }

            }
            per_sample= cur_sample;

        }

    }

}

加载上面的插件后,可以看到分析的结果

所以如果将这份代码放在板卡上运行,首先应该将接收器的信号接到处理器的外部中断管脚,然后注册一个下跳沿触发的快速中断。然后最通常的情况你需要再注册一个标准的输入设备,映射一下遥控器码字和按键事件的对应关系就可以了。

NEC红外遥控协议理解与实现的更多相关文章

  1. 基于STM32的红外遥控重点解析

    本文有两个内容:一.红外遥控协议的的讲解:二.解码程序解析(参考正点原子的代码) 红外的介绍.优点.缺点就不给大家说了,进入正题 一.红外遥控协议的的讲解 红外遥控的编码目前广泛使用的是:NEC Pr ...

  2. 红外遥控NEC协议使用总结

    最近做了一个调试红外遥控三色灯的实习,花了一个多月的时间研究基于NEC协议的红外遥控,下面是这次实习技术方面的总结. 一.NEC协议特征: 8位地址和8位命令长度 每次传输两遍地址(用户码)和命令(按 ...

  3. 46.Linux-分析rc红外遥控平台驱动框架,修改内核的NEC解码函数BUG(1)

    内核版本          :  Linux 3.10.14 rc红外接收类型:  GPIO 类型的NEC红外编码 本章内容 1) rc体系结构分析 2) 分析红外platform_driver平台驱 ...

  4. 基于FPGA的红外遥控解码与PC串口通信

    基于FPGA的红外遥控解码与PC串口通信 zouxy09@qq.com http://blog.csdn.net/zouxy09 这是我的<电子设计EDA>的课程设计作业(呵呵,这个月都拿 ...

  5. 基于Arduino的红外遥控

    1.红外接收头介绍  一.什么是红外接收头?  红外遥控器发出的信号是一连串的二进制脉冲码.为了使其在无线传输过程中免受其他红外信号的干扰,通常都是先将其调制在特定的载波频率上,然后再经红外发射二极管 ...

  6. 基于Arduino、STM32进行红外遥控信号接收

    catalogue . 遥控器原理简介 . 红外遥控原理 . 常见红外遥控器红外线信号传输协议 . 遙控器的发展 . 实验过程 . 攻击面 . 基于STM32实现红外信号解码 1. 遥控器原理简介 0 ...

  7. 46.Linux-创建rc红外遥控平台设备,实现重复功能(2)

    上章链接:46.Linux-分析rc红外遥控平台驱动框架,修改内核的NEC解码函数BUG(1) 在上章分析了红外platform_driver后,已经修改bug后,接下来我们自己创建一个红外platf ...

  8. 玩转X-CTR100 l STM32F4 l 红外遥控接收

    我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ]      X-CTR100控制器具有红外接收头,例程 ...

  9. STM32之红外遥控信号自学习实现

    一.序言 很早前就想实现这个红外遥控自学习的这个实验,用于来自己控制房子里如空调等红外遥控设备的自动化,NEC的标准到具体的产品上可能就被厂家定义为不一样了,所以自学习就应该是接收到什么就发送什么,不 ...

随机推荐

  1. 如何使用Prism框架的EventAggregator在模块间进行通信

    目的 本文主要介绍如何使用Prism类库提供的事件机制在松耦合组件之间相互通信,Prism类库的事件机制建立在事件聚合服务之上,允许发布者和订阅者通过事件进行通信,不需要彼此之间引用. 事件聚合 Ev ...

  2. Subsets 解答

    Question Given a set of distinct integers, nums, return all possible subsets. Note: Elements in a su ...

  3. 解决 VM虚拟机网卡无法拉起 的问题

    复制虚拟机后,第二块网卡始终无法正常运作,表现为无法自动获得dhcp地址,且重启后与第一块网卡使用同样的地址,让人苦笑不得,反复重启了很多次都是这样,后面想到ifcfg-eth1的配置文件可能写得太简 ...

  4. python3 时间和日期

    Python程序可以通过多种方式来处理日期和时间.日期格式之间的转换是计算机的一个共同核心.Python的时间和日历模块能够帮助我们跟踪的日期和时间. 什么是刻度? 时间间隔以秒为单位的浮点数.特别是 ...

  5. sizeof用法

    c语言详解sizeof   原文地址:http://blog.sina.com.cn/s/blog_5da08c340100bmwu.html 一.sizeof的概念   sizeof是C语言的一种单 ...

  6. UVa 836 - Largest Submatrix

    题目:给你一个n*n的01矩阵,求里面最大的1组成的矩形的米娜及. 分析:dp.单调队列.UVa 1330同题,仅仅是输入格式变了. 我们将问题分解成最大矩形.即求解以k行为底边的图形中的最大矩形.然 ...

  7. 求斐波那契数列的第n项

    问题描述:斐波那契数列是这样的一个数列,1,1,2,3,5,8,..,即前两项都是1,后面每一项都是其前面两项的和. 现在要你求出该数列的第n项. 分析:该问题是一个经典的数列问题,相信大家在很多语言 ...

  8. mysql密码忘记如何处理

    1,修改/etc/my.cnf添加添加skip-grant参数,重启mysql. 2,登录mysql  mysql -uroot 3, 更新user中root的密码  use mysql;   upd ...

  9. SQL Server 2008 忘记sa密码的解决办法

    由于某些原因,sa和windows验证都不能登录 sql server,可以用独占模式,修改sa密码先在服务管理器停止Sql Server服务,然后打开命令行,进入 SQL Server安装目录,进入 ...

  10. git push -u origin master 上传出错问题

    ============================================ 跟着廖学锋教程初学git发现个很奇怪的问题,后面原来发现是这样,有点逗.. ================= ...