红外线遥控器解码程序 | 太极博弈原理官方站|紫欽天|融通百科为我所用|生活全智慧|生活智慧之书

正在阅读:

红外线遥控器解码程序

901

这里我们以红外线遥控编码芯片为LC7461等芯片为例来说明用单片机实现红外遥控解码的详细过程,站长琢磨这个解码程序花了相当多的精力,期间几经修改逐步完善,后来还用它开发了几个小产品,希望能对网友学习单片机有所帮助。

    红外线遥控是目前使用最广泛的一种通信和遥控手段。由于红外线遥控装置具有体积小、功耗低、功能强、成本低等特点,因而,继彩电、录像机之后,在录音机、音响设备、空凋机以及玩具等其它小型电器装置上也纷纷采用红外线遥控。工业设备中,在高压、辐射、有毒气体、粉尘等环境下,采用红外线遥控不仅完全可靠而且能有效地隔离电气干扰。

1 红外遥控系统

通用红外遥控系统由发射和接收两大部分组成,应用编/解码专用集成电路芯片来进行控制操作,如图1所示。发射部分包括键盘矩阵、编码调制、LED红外发送器;接收部分包括光、电转换放大器、解调、解码电路。

2 遥控发射器及其编码

遥控发射器专用芯片很多,根据编码格式可以分成脉冲宽度调制和脉冲相位调制两大类,这里我们以运用比较广泛,解码比较容易的脉冲宽度调制来加以说明,现以LC7461组成发射电路为例说明编码原理。当发射器按键按下后,即有遥控码发出,所按的键不同遥控编码也不同。这种遥控码具有以下特征:

采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的“1”

上述“0”和“1”组成的42位二进制码经38kHz的载频进行二次调制以提高发射效率,达到降低电源功耗的目的。然后再通过红外发射二极管产生红外线向空间发射,

7461产生的遥控编码是连续的42位二进制码组,其中前26位为用户识别码,能区别不同的红外遥控设备,防止不同机种遥控码互相干扰。后16位为8位的操作码和8位的操作反码用于核对数据是否接收准确。

当遥控器上任意一个按键按下超过36ms时,LC7461芯片的振荡器使芯片激活,将发射一个特定的同步码头,对于接收端而言就是一个9ms的低电平,和一个4.5ms的高电平,这个同步码头可以使程序知道从这个同步码头以后可以开始接收数据。

解码的关键是如何识别“0”和“1”,从位的定义我们可以发现“0”、“1”均以0.56ms的低电平开始,不同的是高电平的宽度不同,“0”为0.56ms,“1”为1.68ms,所以必须根据高电平的宽度区别“0”和“1”。如果从0.56ms低电平过后,开始延时,0.56ms以后,若读到的电平为低,说明该位为“0”,反之则为“1”,为了可靠起见,延时必须比0.56ms长些,但又不能超过1.12ms,否则如果该位为“0”,读到的已是下一位的高电平,因此取(1.12ms+0.56ms)/2=0.84ms最为可靠,一般取0.84ms左右即可。

    根据红外编码的格式,程序应该等待9ms的起始码和4.5ms的结果码完成后才能读码。

    如果邮购我们开发的51单片机试验板和扩展元件的网友,可以获得如上图所示的红外遥控手柄,这种遥控器的编码格式符合上面的描述规律,而且价格低廉,有32个按键,按键外形比较统一,如果用于批量开发,可以把遥控器上贴膜换成你需要的字符,这为开发产品提供了便利。

接收器及解码

LT0038是塑封一体化红外线接收器,它是一种集红外线接收、放大、整形于一体的集成电路,不需要任何外接元件,就能完成从红外线接收到输出与TTL电平信号兼容的所有工作,没有红外遥控信号时为高电平,收到红外信号时为低电平,而体积和普通的塑封三极管大小一样,它适合于各种红外线遥控和红外线数据传输。

下面是一个对51实验板配套的红外线遥控器的解码程序,它可以把上图32键的红外遥控器每一个按键的键值读出来,并且通过实验板上P1口的8个LED显示出来,在解码成功的同时并且能发出“嘀嘀嘀”的提示音。

ORG 0000H 
AJMP MAIN;转入主程序
ORG 0003H ;外部中断P3.2脚INT0入口地址 
AJMP INT ;转入外部中断服务子程序(解码程序)
;以下为主程序进行CPU中断方式设置
MAIN:SETB EA ;打开CPU总中断请求
SETB IT0 ;设定INT0的触发方式为脉冲负边沿触发
SETB EX0 ;打开INT0中断请求
;以下对单片机的所有引脚进行初始化,全部设置成高电平
MOV P2,#11100111B
AJMP $

;以下为进入P3.2脚外部中断子程序,也就是解码程序
INT: CLR EA ;暂时关闭CPU的所有中断请求
MOV R6,#10
SB: ACALL YS1;调用882微秒延时子程序
JB P3.2,EXIT;延时882微秒后判断P3.2脚是否出现高电平如果有就退出解码程序
DJNZ R6, SB;重复10次,目的是检测在8820微秒内如果出现高电平就退出解码程序 
;以上完成对遥控信号的9000微秒的初始低电平信号的识别。
JNB P3.2, $ ;等待高电平避开9毫秒低电平引导脉冲
ACALL YS2 ;延时4.74毫秒避开4.5毫秒的结果码

MOV R7,#26;忽略前26位系统识别码 

JJJJA:JNB P3.2,$;等待地址码第一位的高电平信号
LCALL YS1;高电平开始后用882微秒的时间尺去判断信号此时的高低电平状态
MOV C,P3.2;将P3.2引脚此时的电平状态0或1存入C中
JNC UUUA;如果为0就跳转到UUUA
LCALL YS3;检测到高电平1的话延时1毫秒等待脉冲高电平结束
UUUA: DJNZ R7,JJJJA

MOV R1,#1AH ;设定1AH为起始RAM区
MOV R2,#2;接收从1AH到1BH的2个内存,用于存放操作码和操作反码 
PP: MOV R3,#8;每组数据为8位 

JJJJ: JNB P3.2,$;等待地址码第一位的高电平信号
LCALL YS1;高电平开始后用882微秒的时间尺去判断信号此时的高低电平状态
MOV C,P3.2;将P3.2引脚此时的电平状态0或1存入C中
JNC UUU;如果为0就跳转到UUU
LCALL YS3;检测到高电平1的话延时1毫秒等待脉冲高电平结束
UUU: MOV A,@R1;将R1中地址的给A
RRC A;将C中的值0或1移入A中的最低位
MOV @R1,A;将A中的数暂时存放在R1数值的内存中
DJNZ R3,JJJJ;接收满8位换一个内存
INC R1;对R1中的值加1,换下一个RAM
DJNZ R2,PP ;接收完8位数据码和8位数据反码,存放在1AH/1BH中

MOV A,1AH
CPL A;对1AH取反后和1BH比较
CJNE A,1BH,EXIT;如果不等表示接收数据发生错误,放弃

MOV P1,1AH;将按键的键值通过P1口的8个LED显示出来!
CLR P2.5;蜂鸣器鸣响-嘀嘀嘀-的声音,表示解码成功
LCALL YS2
LCALL YS2
LCALL YS2
SETB P2.5;蜂鸣器停止
EXIT: SETB EA ;允许中断
RETI ;退出解码子程序

YS1: MOV R4,#20 ;延时子程序1,精确延时882微秒
D1: MOV R5,#20
DJNZ R5,$
DJNZ R4,D1 
RET
YS2: MOV R4,#10 ;延时子程序2,精确延时4740微秒
D2: MOV R5,#235
DJNZ R5,$
DJNZ R4,D2 
RET
YS3: MOV R4,#2;延时程序3,精确延时1000微秒
D3:MOV R5,#248
DJNZ R5,$
DJNZ R4,D3
RET
END

0A
   
01
11
12
13
14
15
16
17
18
19
10
1A
1B
0E
02
03
1C
06
04
05
0C
0D
08
09
1D
00
1F
1E
0B
07
   
0F

这是按照红外遥控器按键的实际位置给出的32个按键的键值(16进制)

 

编者按:以下是网友编写的遥控解码程序!一种用延时等待的解码方法,比较容易理解,但缺点是占用CPU运行时间,第二种方法用定时器和外中断的解码方法,初学不易理解,但优点也很明显,第二种方法如果能解决连发解码就比较完美,更完善的红外遥控解码程序,请参考本站TOPAV-2008,TOP51-2005所配程序。

 

解码方法一

 

;//单片机接收红外解读程序\
;硬件结构:8951,P0口数码管段码,P2.0-P2.3为位,P1为8个LED
;P3.2为红外接收头,P2.7蜂鸣器,晶振12M
;适用UPD6121 6122芯片接收
;---------------------------------------------------------

 

ORG 0000H 
AJMP MAIN ;转入主程序
ORG 0003H ;外部中断P3.2脚INT0入口地址 
AJMP INT ;转入外部中断服务子程序(解码程序)

 

;以下为主程序进行CPU中断方式设置
MAIN: SETB EA ;打开CPU总中断请求
SETB IT0 ;设定INT0的触发方式为脉冲下降沿触发
SETB EX0 ;打开INT0中断请求

 

AJMP $
;以下为进入P3.2脚外部中断子程序,也就是解码程序
INT: CLR EA ;暂时关闭CPU的所有中断请求
MOV R6,#10
SB: ACALL YS1 ;调用882微秒延时子程序
JB P3.2,EXIT ;延时882微秒后判断P3.2脚是否出现高
; 电平如果有就退出解码程序
DJNZ R6, SB ;重复10次,目的是检测在8820微秒内
;如果出现高电平就退出解码程序
;以上完成对遥控信号的9000微秒的初始低电平信号的识别。
JNB P3.2, $ ;等待高电平避开9毫秒低电平引导脉冲
ACALL YS2 ;延时4.74毫秒避开4.5毫秒的结果码
MOV R1,#1AH ;设定1AH为起始RAM区
MOV R2,#4

 

;
PP: MOV R3,#8
JJJJ: JNB P3.2,$ ;等待地址码第一位的高电平信号
LCALL YS1 ;高电平开始后用882微秒的时间尺去判断信
;号此时的高低电平状态
MOV C,P3.2 ;将P3.2引脚此时的电平状态0或1存入C中
JNC UUU ;如果为0就跳转到UUU
LCALL YS3

 

;
UUU: MOV A,@R1 ;将R1中地址的给A
RRC A ;将C中的值0或1移入A中的最低位
MOV @R1,A ;将A中的数暂时存放在R1中
DJNZ R3,JJJJ ;接收地址码的高8位
INC R1 ;对R1中的值加1,换下一个RAM
DJNZ R2,PP ;接收完16位地址码和8位数据码和8位数据反
; 码,存放在1AH/1BH/1CH/1DH的RAM中

 

MOV A,1CH ;比较数据码和数据反码是否正确?
CPL A
XRL A,1DH ;将1CH的值取反后和1DH比较 不同则无效丢弃,核对数据是否准确
JNZ EXIT

 

MOV DPTR,#TAB ;表头地址送指针
MOV A,1DH
ANL A,#0FH ;相与,得到低四位码
MOVC A,@A+DPTR
MOV 1EH,A ;查表得表码存入1EH

 

MOV A,1DH
SWAP A 
ANL A,#0FH 
MOVC A,@A+DPTR
MOV 1FH,A ;查表得高四位码存入1F

 

MOV R7,#20H 
DISP:
MOV P0,1FH ;送数码管显示
CLR P2.1
ACALL YS2
SETB P2.1

 

MOV P0,1EH
CLR P2.2
ACALL YS2
SETB P2.2

 

MOV P1,1DH ;将按键的键值通过P1口的8个LED显示出来!
CLR P2.7 ;蜂鸣器鸣响-嘀嘀嘀-的声音,表示解码成功
LCALL YS2
SETB P2.7 ;蜂鸣器停止
DJNZ R7,DISP

 

EXIT: SETB EA ;允许中断
RETI ;退出解码子程序

 

YS1: MOV R4,#20 ;延时子程序1,精确延时882微秒
D1: MOV R5,#20
DJNZ R5,$
DJNZ R4,D1 
RET
YS2: MOV R4,#10 ;延时子程序2,精确延时4740微秒
D2: MOV R5,#235
DJNZ R5,$
DJNZ R4,D2 
RET
YS3: MOV R4,#2 ;延时程序3,精确延时1000微秒
D3:MOV R5,#248
DJNZ R5,$
DJNZ R4,D3
RET

 

TAB: DB 0C0H,0DEH,0A2H,8AH,9CH,89H,81H,0DAH,80H,88H,90H,85H,0E1H,86H,0A1H,0B1H;数据表,0-9-A-F
END

 
解码方法二

 

你的解码程序和我现在用的解码程序大体是一样的,我自己实际做了一下,发现按下遥控器,接收到红外信号后,数码管闪的厉害。我用的是6位动态数码管。不知道你有没有遇到这样的情况?
分析解码程序,感觉是中断的时间太长了,数码管当然会闪了。如果把数码管用定时器刷新的话,又存在定时中断和外中断的优先级问题,好难解决啊。
我初步有个想法。就是用定时器计算两次外中断间隔的时间。以此来确定是连发码,数据“0”,数据“1”。不知道这个想法可否行的通。这几天没有时间试,因为广州有个电子产品交易会,我要赶着做样机。过了几天我有空了在仔细的做一遍。把结果告诉大家。

 

不用连续解码,只需在中断时读取定时器的时间,然后判断是0或者1就可以了,实际测试已经OK了,谢谢两位的热心帮助。
为了这个程序,弄了两天的时间,饭都吃不好,现在弄通了,感觉真的很好。
我现在用6个数码管显示遥控器的用户码,用户反码,按键码,无论怎么按遥控器,数码管都不会闪的。

 

楼上的,我是这样解决闪烁问题的,用显示子程序计算出适当次数代替延时YS1 YS2 YS3子程序

 

;======================================================================================
;红外解码程序
;晶体:11.0592M
;日期:2005-10-14
;功能:将6122发射IC发射的红外码解码,储存在CODE1--CODE4中,并用6个数码管显示用户码,用户反码,按键码 
;======================================================================================
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP REMOT
ORG 000BH
AJMP TIME0
;------------------------------------------------------
IR BIT P3.2

 

CODE1 EQU 30H ;遥控用户码
CODE2 EQU 31H ;遥控用户反码
CODE3 EQU 32H ;按键码
CODE4 EQU 33H ;按键反码

 

TIME1_REMOT EQU 34H ;每次接收的码BIT数
TIME2_REMOT EQU 35H ;允许重码次数
TIME3_REMOT EQU 36H ;按键数目存放
;---------------------------------------------------------

 

DIG1 BIT P2.1;第一位数码管选通
DIG2 BIT P2.5;第二位数码管选通
DIG3 BIT P2.0;第三位数码管选通
DIG4 BIT P2.4;第四位数码管选通
DIG5 BIT P2.6;第五位数码管选通
DIG6 BIT P2.3;第六位数码管选通

 

;----------------------------------------
D1 EQU 40H
D2 EQU 41H
D3 EQU 42H
D4 EQU 43H
D5 EQU 44H
D6 EQU 45H

 

ORG 0030H
;=============================初始化===============================

 

MAIN:
SETB EA ;开总中断
MOV TMOD,#1H ;定时器0工作于方式1

 

SETB ET0 ;启动定时器0
SETB TR0

 

MOV TH0,#0 ;预置数0
MOV TL0,#0

 

SETB EX0 ;开外中断0
SETB IT0

 

MOV TIME1_REMOT,#32;接收的码一共32BIT:4*8

 

CLR P1.0
MOV D1,#10H
MOV D2,#10H
MOV D3,#10H
MOV D4,#10H
MOV D5,#10H
MOV D6,#10H
;============================初始化完毕============================

 

;=============================主程序==============================
LOOP:
; ACALL FENLI
ACALL DIG
AJMP LOOP
;=============================主程序完毕==========================

 

;=============================红外解码中断程序=========================
;=============================================
;以下为红外中断解码程序
;接收头引脚P3.2
;按键反码: CODE1
;按键码:CODE2
;用户反码: CODE3
;用户码:CODE4
;接收码的BIT数:TIME1_REMOT
;重码次数:TIME3_REMOT;
;入口函数:
;出口函数:R0---按键反码 R1----按键码 R2---用户反码 R3----用户码 R4---按键标准键值
;=============================================
REMOT:
CLR EA ;关总中断
PUSH ACC
PUSH PSW
PUSH DPH
PUSH DPL

 

CLR P1.7
;-----------------判断定时器运行时间是否大于12.288MS-----------------
MOV A,TH0 ;读入此时TH0,判断是否大于设定的数
CLR C ;清除C避免误判
SUBB A,#2CH ;11.0592-2C 12M-30 6M-18 4M-10 24M-60
JC REMOT1 ;小于12.220往下判断
AJMP EXIT_REMOT1 ;大于2BFF*1.085=12.220MS则退出

 

;-----------------判断定时器运行时间是否小于0.768MS------------------
REMOT1:
MOV A,TH0
CLR C
SUBB A,#23H ;11.0592-2 12M-3 6M*-1 4M-1 24M-6
JNC REMOT2
AJMP EXIT_REMOT ;小于0.768作误码,退出
;------------------判断定时器运行时间是否小于2MS---------------------
REMOT2:
MOV A,TH0
CLR C
SUBB A,#7H ;11.0592-7 12M-7 6M-3 4M-2 24M-0FH
JC REMOT4
AJMP REMOT3 ;小于2MS,做数据:"0:处理
;-----------------判断定时器运行时间是否小于11.5MS-------------------
REMOT3:
MOV A,TH0
CLR C
SUBB A,#29H ;11.0592-29 12M-2C 6M-16 4M-0EH 24M-59
JC REMOT5 ;小于11.5MS,做数据"1"处理
AJMP REMOT6 ;否则作重码处理
;----------------数据"0"----------------------
REMOT4:
CLR C
AJMP REMOT7
;----------------数据"1"--------------------
REMOT5:
SETB C
AJMP REMOT7
;----------------重码------------------------
REMOT6:
DJNZ TIME3_REMOT,EXIT_REMOT
MOV TIME3_REMOT,#2
AJMP EXIT_REMOT1

 

;---------------储存数据--------------------
REMOT7:
MOV A,CODE1
RRC A
MOV CODE1,A
MOV A,CODE2
RRC A
MOV CODE2,A
MOV A,CODE3
RRC A
MOV CODE3,A
MOV A,CODE4
RRC A
MOV CODE4,A
DJNZ TIME1_REMOT,EXIT_REMOT
MOV TIME1_REMOT,#32;判断是否接收完32位,
MOV R0,CODE1
MOV R1,CODE2
MOV R2,CODE3
MOV R3,CODE4

 

AJMP BIJIAO ;此处设置断点,R0--按键反码
;R1---按键码
;R2---用户反码
;R3---用户码
;---------------用户码判断-------------------------
BIJIAO:
; MOV A,CODE4
; CJNE A,#10H,EXIT_REMOT
; MOV A,CODE3
; CJNE A,#0EFH,EXIT_REMOT
;---------------按键码判断-----------------------
MOV A,CODE2
CPL A
XRL A,CODE1
JNZ EXIT_REMOT
ACALL FENLI
AJMP EXIT_REMOT1
;--------------将按键码转换为标准的码值-----------
OK_REMOT:
MOV TIME3_REMOT,#15 ;按键数:15个按键
MOV R4 DPTR,#TAB_REMOT ;指针指向按键码值表
OK_REMOT1:
MOV A,TIME3_REMOT ;将码值表第一个数与CODE2比较
MOVC A,@A+DPTR
XRL A,CODE2
JZ OK_REMOT2 ;相同,已经找到,跳转出口
DJNZ TIME3_REMOT,OK_REMOT1;不同,未找到,取下一个按键码值比较,直到相同为止
AJMP EXIT_REMOT1 ;已经找完码值表,未找到匹配数据,退出
;-------------
OK_REMOT2:
MOV R4,TIME3_REMOT ;将标准码值存入R4
AJMP EXIT_REMOT

 

;--------------------按键码值表------------------------
TAB_REMOT:
DB 0H
;SETB
;ST.BY-INPUT-REST
DB 04H,02H,06H
;
;FR- MAST+ FR+
DB 0EH,07H,00H

 

; ;SUB- MUTE SUB+
DB 10H,0FH,12H

 

; ;CEN- MAST+ CEN+
DB 13H,03H,0AH

 

; ;SUR- SET75 SUR+
DB 11H,08H,01H

 

;---------------解码中断退出程序--------------------
EXIT_REMOT1: ;异常退出
MOV TIME1_REMOT,#32
EXIT_REMOT: ;正常退出
MOV TH0,#0 ;重设定时器0
MOV TL0,#0
SETB EA
SETB TR0 ;开中断
; SETB EX0

 

CLR IE0 ;清外中断标志,避免反复中断
POP DPL
POP DPH
POP PSW
POP ACC ;出栈
SETB P1.7
RETI

 

;=========================红外解码中断程序完毕====================
;=========================定时中断程序============================
;============================================================
;以下为定时器中断程序
;功能:每120MS清除遥控用户码缓存
;入口函数:
;出口函数:
;============================================================
TIME0:
CLR EA
MOV TH0,#0
MOV TL0,#0
MOV CODE1,#0
MOV CODE2,#0
MOV CODE3,#0
MOV CODE4,#0
SETB EA
RETI
;==============================================================
;=======================以下为数码管显示数分离子程序================

 

; ;功能:将遥控器的用户码,用户反码,按键码,的十位与个位分离
;入口函数:R3--用户码,R2--用户反码,R1---按键码
;出口函数:D1-用户码十位,D2--用户个位,D3--用户反码十位,D4---用户反码个位,
; ;D5---按键码十位,D6---按键码个位
;----------------------------------------------------------
FENLI:
MOV A,R3 ;分离用户反码
MOV B,#16
DIV AB
MOV D1,A
MOV D2,B

 

MOV A,R2 ;分离用户码
MOV B,#16
DIV AB
MOV D3,A
MOV D4,B

 

MOV A,R1 ;分离按键码
MOV B,#16
DIV AB
MOV D5,A
MOV D6,B
RET
;-----------分离完毕-------------------------
;===================以下为数码管显示子程序=======================
;入口函数:D1---D6
;--------------------------------------------------------------
DIG:
MOV DPTR,#TAB_DIG ;显示用户反码十位
MOV A,D1
MOVC A,@A+DPTR
MOV P2,#0FFH
MOV P0,A
CLR DIG1
ACALL YS2MS

 

MOV DPTR,#TAB_DIG ;显示用户反码个位
MOV A,D2
MOVC A,@A+DPTR
MOV P2,#0FFH
MOV P0,A
CLR DIG2
ACALL YS2MS

 

MOV DPTR,#TAB_DIG ;显示用户码十位
MOV A,D3
MOVC A,@A+DPTR
MOV P2,#0FFH
MOV P0,A
CLR DIG3
ACALL YS2MS

 

MOV DPTR,#TAB_DIG ;显示用户码个位
MOV A,D4
MOVC A,@A+DPTR
MOV P2,#0FFH
MOV P0,A
CLR DIG4
ACALL YS2MS

 

MOV DPTR,#TAB_DIG ;显示按键码十位
MOV A,D5 MOVC A,@A+DPTR MOV P2,#0FFH MOV P0,A CLR DIG5 ACALL YS2MS MOV DPTR,#TAB_DIG ;显示按键码个位 MOV A,D6
MOVC A,@A+DPTR
MOV P2,#0FFH
MOV P0,A
CLR DIG6
ACALL YS2MS
;---------------------------显示完毕-----------------------------------
RET
;------------------------------数码管段码表------------------------------------
TAB_DIG: ;0 1 2 3 4 5 6 7 8 9 A B C D E F 全亮 消隐
DB 5H,0B7H,51H,31H,0A3H,29H,9H,37H,1H,21H,3H,89H,4DH,4DH,49H,4BH,0h,0ffh
;------------------------------延时-------------------------------------------
YS2MS:
MOV R7,#15
DEL1:MOV R6,#100
DJNZ R6,$
DJNZ R7,DEL1
RET

 

END

抱歉,这篇文章关闭了评论功能。

关闭