sword_yang 发表于 2010-8-28 09:04:59

【开源项目】单片机在音响上的应用(四):红外遥控解码

作者:sword__yang
       红外遥控已经广泛地用在音响产品中,下面我们将以NEC的红外遥控发射芯片uPD6121的编码格式为例,介绍如何用MCU来做NEC格式的红外遥控解码。
       uPD6121红外遥控发射集成电路采用用NEC的传输格式,目前广泛地应用在电视机,录像机,音响设备,空调机等家电产品上。结合外部二极管和电阻器可以做成客户自己定义的编码,最高可以获得65536种遥控编码。该芯片体积小,功耗低,可以做成外形小巧的红外遥控发射器。图II-4.0是该芯片的引脚及功能方框图,遥控器的应用电路图请参见图II-4.1,客户编码电阻和二极管接入位置的改变,可以改变数据流的客户编码部分,可以用来区分不同厂家、不同种类产品的遥控器。
       NEC的传输格式由引导码、客户编码( 16位)、数据码( 16位)和持续脉冲等部分。图II-4.2和图II-4.2是它们各个部分的波形,对于这些波形,一定要仔细地分析,否则解码就无从入手了 。

http://cache.amobbs.com/bbs_upload782111/files_32/ourdev_578263.jpg
(原文件名:1.jpg)

http://cache.amobbs.com/bbs_upload782111/files_32/ourdev_578264.jpg
(原文件名:2.jpg)

http://cache.amobbs.com/bbs_upload782111/files_32/ourdev_578265.jpg
(原文件名:3.jpg)

http://cache.amobbs.com/bbs_upload782111/files_32/ourdev_578266.jpg
(原文件名:4.jpg)

分析:
NEC格式的红外遥控码的主要特征:
以两个脉冲之间的间隔时间长短来区分各种不同的遥控指令的信息含义。
1)引导码:前高(9mS)+ 后低(4.5mS) = 13.5mS。
2)信息码:信息码包括客户编码和数据码,它们都是以两个脉冲上升沿之间的间隔长短为“BIT 0”或者“BIT 1”的识别特征的:
   a)两个脉冲上升沿之间的间隔 = 1.125mS: 数据BIT = 0;
   b)两个脉冲上升沿之间的间隔 = 2.25mS:数据BIT = 1。
3)持续码:当按键一直按下时,遥控指令在发送了第一组信息码后,就不再重复发送信息吗,这时改为发送一种持续码:
“前高(9mS)”+ “后低(2.25mS)” = 11.25mS
抓住了这三个主要特征,我们就可以利用16F873A MCU的CCP(Capture/Compare/PWM 捕捉/ 比较/ 脉宽调制) 模块的“时间捕捉”来实现脉冲间隔的捕捉。
每个16F873A的CCP模块有一个16位的捕捉寄存器:CCPRxH/CCPRxL,和一个CCPxCON控制寄存器,可以设定CCPxCON为对应于CCP引脚上每一个上升沿到来就产生一次捕捉中断,这时候MCU内部的定时器TIMER1的计数值就自动赋给捕捉寄存器CCPRxH/CCPRxL,第N+1次捕捉寄存器的值减去第N次的捕捉寄存器的值,就是这两次上升沿之间的间隔时间。利用CCP的时间捕捉功能,我们就可以把遥控码的信息解调出来了。
       解码算法:
       第一步:通过标志位变量FLG2,FIRST,以及一个复位计时器完成接收准备。当遥控脉冲串停止150 mS后,复位计时器减数为0, 复位FLG2,FIRST,这样就可以在下一个遥控指令到来时,把遥控码的第一个上升沿识别出来。
1-1:每次遥控接收头来的上升脉冲产生一次CCP中断,中断服务子程序检测是否第一个脉冲上升沿(FLG2,FIRST为低)?
1-2:不是,跳去2-1做宽度判别;是第一个脉冲上升沿,清TIMER1定时器、清CCP寄存器、清上次时间暂存变量打开开TIMER1为捕捉做准备。
      第二步:识别引导码:
2-1:读出CCP寄存器捕捉到的时间值,减去上一次的时间值,判断标志变量FLG2,DATA_EN数据接收是否开始?
2-2:已经开始,转3-1判断是数据“0”还是数据“1”的判断;没有开始,比较捕捉到的时间是否大于11.25mS?
2-3:若不大于,说明是持续脉冲,转5-1持续脉冲处理;若大于,说明是引导码,设数据接收开始标志位FLG2,DATA_EN为高,准备接收数据。
         第三步:是数据“0”还是数据“1”的判断:
3-1:捕捉到的时间值是否大于1.125mS ?
3-2:大于,设标志位变量FLG2,C_STATS为高;不大于,设为低(把判断结果带到后面的处理);
3-3:判断是否接收完客户码1(8个BIT)?
3-4:是,存入客户码1,转3-5;不是,继续接收;
3-5:是否接收完客户码2(8个BIT)?
3-6:是,存入客户码2,转3-7;不是,继续接收;
3-7:是否接收完数据原码(8个BIT)?
3-8:是,存入数据原码,转3-9;不是,继续接收;
3-9:是否接收完数据反码(8个BIT)?
3-10:是,存入数据反码,转4-1;不是,继续接收;
         第四步:比较客户码是否有效(客户码是客户设定的常量);
4-1:客户码1=设定值吗?
4-2:等于,转4-3;不等于设定值,接收无效退出(不是我的遥控器!);
4-3:客户码2=设定值吗?
4-4:等于,转4-5;不等于设定值,接收无效退出(两个客户码不相等,有误码);
4-5:遥控数据比较:原码异或(XOR)反码=0FFH ?(数据是否相等);
4-6:是,数据有效,遥控码成功解出;不是,数据无效退出。
         第五步:持续码处理:
5-1:持续脉冲是否连续3次?(这是调整持续按键动作的间隔用的,例如调整音量持续改变的快慢);
5-2:是,转5-3;不是,退出;
5-3:是否不能持续操作的遥控码?(如电源开关、静音等是不能持续操作的);
5-4:不是,转5-4;是,不做持续处理,退出;
5-5:从备份寄存器恢复有效接收码,退出。
5-6:若持续脉冲还在发送,继续5-1。
         算法完成。
【小结】:看似很复杂的NEC码流,其实我们只需要抓住是“持续脉冲”还是“引导码”;是数据“0”还是数据“1”这两个关键的判断点,就可以轻松解调出遥控信息了。
NEC格式遥控解码例程如下:
变量说明:
TIMR1H/TIMR1L: MCU的TIMER1定时寄存器
CCPR1H/CCPR1L: MCU的CCP捕捉寄存器
TLAH/TLAL:            上次捕捉到的时间值
DELTH/DELTL:       本次-上次=本次时间增量
CUSTOI:               客户码1
CUSTOB:            客户码2
DATAI:                  数据原码
DATAB:               数据原码
RX:                        数据类型导向计数
VALID:                  有效遥控码
VALIB:                  有效遥控码备份
位变量:
FLG2,FIRST:      首个脉冲标志位(当收到CCP中断时,如果本位为低,说明是第一个脉冲)
FLG2,DATA_EN:数据接收开始标志位,本位为高,数据串接收开始
FLG2,C_STATUS:数据“1”标志,当收到的数据BIT判定为1,本位为高
;===========================================
;             TIMER CAPTURE MODE
;          REMOCON RECEIVE & DECODE
;===========================================
CCP_INT:         
                MOVWF   W_TEMP                ; 保护W寄存器现场
                SWAPF      STATUS,W
                BCF         STATUS,RP0
                MOVWF   STATUS_TEMP      ; 保护状态寄存器现场
                BCF         PIR1,CCP1IF
                MOVLW   .3                            ; 给遥控复位计数器赋值   
                MOVWF   FIRST_RESET       ; 3X50mS=150mS(基本定时中断为50mS一次)
                BTFSC       FLG2,FIRST          ; 判断是否是第一个脉冲?
                GOTO      RC_0                     ; 不是,跳去做宽度鉴别                        
                BSF            FLG2,FIRST          ; 是,取消第一脉冲标志
                CLRF         TMR1H                   ; 清TIMER1定时寄存器高位
                CLRF         TMR1L                   ; 清TIMER1定时寄存器低位
                CLRF         CCPRL                   ; 清CCP捕捉寄存器低位
                CLRF         CCPRH                   ; 清CCP捕捉寄存器高位
                CLRF         TLAL                     ; 清上次时间值低位
                CLRF         TLAH                     ; 清上次时间值高位
                BSF            T1CON,TMR1ON    ; 开定时器1
                GOTO         RC_EX                   ; 退出
RC_0:         
                MOVF         TLAH,W                  ; 脉冲宽度鉴别开始
                SUBWF       CCPR1H,W             ; 计算时间增量
                MOVWF      DELTH                  
                MOVF         CCPR1H,W   
                MOVWF      TLAH                      ; 刷新“上次”时间值
RC_1:
               MOVF          DELTH,W
               BTFSC         FLG2,DATA_EN    ; 数据接收开始?
               GOTO          DATAIN                  ; 是,去数据接收脉宽判别
                SUBLW      0X30                      ; 引导码脉宽判别
                BTFSC      STATUS,C             ; 是引导码?
                GOTO         CONTIN               ; 不是,跳到持续脉冲处理
                MOVLW       0X80                     ; 是,清理数据接收寄存器
                MOVWF       CUSTOI                ; 为数据接收做好准备      
                MOVWF       CUSTOB   
                MOVWF       DATAI                   ; 设最高位为1是为了后面利用数据右移位来移入BIT串      
                MOVWF       DATAB   
                BSF             FLG2,DATA_EN    ; 设数据开始标志            
                CLRF          RX
                CLRF          CONTC                  ; 清持续脉冲计数器
                GOTO         RC_EX                   ; 退出
DATAIN:         
                MOVF         DELTH,W   
                SUBLW       .7   
                BTFSC       STATUS,C            ; 数据位“0”/“1”判别
                GOTO      RC_2   
                BSF            FLG2,C_STATUS   ; 为“1”,设“1”标志位
                GOTO      RC_3   
RC_2:      
               BCF             FLG2,C_STATUS    ; 为“0”,清“1”标志位      
RC_3:
               MOVF          RX,W
               SUBLW      .0                           ; 数据类别导向
               BTFSC      STATUS,C
               GOTO         CUSTO_I                  ; RX=0:客户码1
               MOVF         RX,W
               SUBLW       .1
               BTFSC       STATUS,C
               GOTO      CUSTO_B                  ; RX=1:客户码2
               MOVF         RX,W
               SUBLW       .2
               BTFSC      STATUS,C
               GOTO         DATA_I                     ; RX=2:数据原码
               MOVF          RX,W
               SUBLW      .3
               BTFSC      STATUS,C
               GOTO         DATA_B                   ; RX=3:数据反码
               GOTO         RC_EX                     ; 以上都不是=误码,退出
CUSTO_I:
               BTFSS      FLG2,C_STATUS   ; 数据位标志为高?
               GOTO         CI_0
               BSF            STATUS,C                ; 是,设进位位为高
               GOTO      CI_1
CI_0:
               BCF            STATUS,C                ; 不是,清进位位
CI_1:
               RRF            CUSTOI                  ; 客户码1右移一位   
               BTFSS      STATUS,C                ; 共移动了8次吗?
               GOTO         RC_EX                      ; 不是,退出
               INCF            RX                            ; 是,客户码1接收完成,导向变量加1
            GOTO          RC_EX
CUSTO_B:
               BTFSS      FLG2,C_STATUS   ; 客户码2移位接收,与客户码1接收到过程相同
               GOTO         CB_0
               BSF             STATUS,C
               GOTO         CB_1
CB_0:
               BCF            STATUS,C
CB_1:
               RRF         CUSTOB
               BTFSS       STATUS,C
               GOTO      RC_EX
               INCF          RX
               GOTO       RC_EX
DATA_I:
               BTFSS      FLG2,C_STATUS       ; 数据原码移位接收,与客户码1接收到过程相同
               GOTO       DI_0
               BSF         STATUS,C
               GOTO       DI_1
DI_0:
               BCF          STATUS,C
DI_1:
               RRF          DATAI
               BTFSS      STATUS,C
               GOTO       RC_EX
               INCF          RX
               GOTO       RC_EX
DATA_B:
               BTFSS      FLG2,C_STATUS         ; 数据反码移位接收,与客户码1接收到过程相同
               GOTO       DB_0
               BSF         STATUS,C
               GOTO       DB_1
DB_0:
               BCF          STATUS,C
DB_1:
               RRF         DATAB
               BTFSS   STATUS,C
               GOTO      RC_EX
               CLRF       RX   
CUST:         
               BCF         FLG2,DATA_EN             ; 客户码对照,清数据接收允许标志
               BCF         FLG2,FIRST                   ; 清第一个脉冲标志,准备下次接收
               MOVLW   #CUSTOM_CODE   
               SUBWF   CUSTOI,W                      ; 比较客户码1
               BTFSS    STATUS,Z
               GOTO   RC_EX                           ; 不同,不是本机的遥控器   
               MOVF   CUSTOB,W   
               XORLW   #CUSTOM_CODE          ; 相同,比较客户码2(通常是客户码1的反码)   
               SUBLW    0XFF   
               BTFSS   STATUS,Z
               GOTO   RC_EX                           ; 不同,不是本机的遥控器            
DATACM:         
               MOVF      DATAI,W                         ; 相同,验证数据码
               XORWF   DATAB,W   
               SUBLW    0XFF   
               BTFSS   STATUS,Z
               GOTO   RC_EX                            ; 原码和反码验证失败,退出            
               MOVF      DATAI,W      
               MOVWF   VALID                            ; 原码和反码验证OK,保存码值到VALID
               MOVWF   VALIB                            ; 备份码值到VALIB,为持续按键处理做准备                        
               GOTO   RC_EX   
CONTIN:         
               INCF       CONTC                           ; 持续脉冲处理,持续计数器加1
               MOVF   CONTC,W
               SUBLW    .3
               BTFSC    STATUS,C                     ; 持续收到3次?
               GOTO   RC_4                           ; 不是,去清理标志
               MOVLW   .0                                 ; 是,清计数器
               MOVWF   CONTC
               MOVF      VALIB,W   
               SUBLW   #ON/OFF_CODE          ; 检验是否不允许做持续操作的遥控码
               BTFSC   STATUS,Z                     ; 是 ON/OFF 键吗?
               GOTO      RC_4                            ; 是,不做持续处理退出
               MOVF      VALIB,W   
               SUBLW    #MUTE_CODE
               BTFSC   STATUS,Z                     ; 是 MUTE 键吗?
               GOTO      RC_4                           ; 是,不做持续处理退出            
               MOVF       VALIB,W   
               MOVWF   VALID                           ; 不是,把原来备份数据恢复到键值寄存器VALID
RC_4:         
               BCF         FLG2,FIRST                   ; 清第一个脉冲标志
               BCF         FLG2,DATA_EN             ; 清数据接收允许标志
RC_EX:         
               SWAPF    STATUS_TEMP,W          ; 恢复状态寄存器
               MOVWF   STATUS
               SWAPF    W_TEMP,F
               SWAPF    W_TEMP,W                   ; 恢复W寄存器
               RETFIE                                          ; 退出CCP中断服务子程序

90999 发表于 2010-8-28 10:01:35

你别说,我的红外解码就是做不好,超薄的遥控器只有半米的距离,而手持型2-3米~~~~~

在范围之内就可以解,范围之外就解不了。时间值调过了,接收头换过了,没有用,怪了。

sword_yang 发表于 2010-8-28 10:39:02

我们的产品都要经过6米距离测试。

90999 发表于 2010-8-28 17:32:40

回复【2楼】sword_yang   
我们的产品都要经过6米距离测试。
-----------------------------------------------------------------------

产品当然要经过测试,不然怎么对客户负责~

sword_yang 发表于 2010-8-28 17:45:14

我要告诉你的不是要测试,而是要做多少米的测试。

sword_yang 发表于 2010-8-28 17:46:50

6米距离不能有效遥控的都是废品。

kiven_chen 发表于 2010-8-31 08:25:12

怎么才能收藏帖子啊。

sword_yang 发表于 2010-8-31 09:10:30

点击IE(或者你用的其他浏览器)的“收藏夹”,添加即可。

mjsong 发表于 2010-9-4 00:14:48

排排坐 听杨老师讲课
有个闲置品牌机机箱 元件也备了大部分 打算动手了

XMLK 发表于 2010-12-4 00:26:53

MARK

leolink 发表于 2010-12-4 00:37:11

mark

feixuehanyi 发表于 2011-3-19 22:34:56

mark

reflecter 发表于 2011-3-20 03:20:28

Mark一下,这是我做的第一个软件项目内容~

xrwf_2009 发表于 2011-3-20 09:20:31

记号 红外解码

xunke 发表于 2011-3-20 16:05:33

不错!

ljh999 发表于 2011-3-22 21:22:29

来听杨老师讲课了!

sherlockljt 发表于 2011-4-23 01:32:13

mark

nop_linyh 发表于 2011-4-25 18:03:11

mark

cunlingwang 发表于 2011-5-26 16:27:47

mark

mook_dj 发表于 2011-5-26 16:54:35

我做过用单片机解码CD机摇控,距离>16米,当然接近16米,时摇控要对得准确才可以正常解码.10米以内随随便便.

xingyunma 发表于 2011-12-21 16:11:35

mark

Hot_Blood 发表于 2012-1-16 00:30:19

mark

zjk 发表于 2014-1-24 14:49:45

mark,标记一下

ren_919 发表于 2014-1-25 12:13:12

记住你!

stevenh 发表于 2015-10-21 18:04:17

谢谢分享!

lxa0 发表于 2018-1-13 16:26:50

50462比nec的功能多
页: [1]
查看完整版本: 【开源项目】单片机在音响上的应用(四):红外遥控解码