📄 ir_decoder.asm
字号:
;* 红外线遥控解码 *
;***************************************************************************
;* 标题:红外线遥控解码器 *
;* 日期:2004.8.23 *
;* 程序编写 : 吴巍(wuwei) *
;* E-mail:cdream5@163.com *
;* 网址: Http://www.cdream5.com *
;* 说明:该程序实现将红外遥控器发出的红外线解码,并通过LCD显示出来 *
;***************************************************************************
;*注:显示来的编码顺序为:ID原码、ID反码、操作原码、操作反码 *
;* 程序解的是NEC6121/2格式的编码,其他编码请修改解码程序部分 *
;***************************************************************************
;***************************************************************************
;连线图: *LCM---89C51* *LCM---89C51* *LCM------------89C51*
; | | | | | |
; *DB0---P0.0* *DB4---P0.4* *RS-------------P1.6*
; *DB1---P0.1* *DB5---P0.5* *RW-------------P1.7*
; *DB2---P0.2* *DB6---P0.6* *E--------------P3.4*
; *DB3---P0.3* *DB7---P0.7* *VLCD接10K可调电阻到GND*
; *IR single input---->P3.3*
;注:单片机89C51/C52/S51/S52 晶振12Mhz
;**************************************************************************
ORG 0000H
AJMP boot
ORG 00013H ;外部中断P3.3脚INT1入口地址
AJMP INT
ORG 030H
boot:
CODE_BASE EQU 0031h
STACK_START EQU 36h
ir_code data 60H ;操作码
ir_code_R data 61h ;操作码反码
ir_ID_code data 62h ;用户码
ir_id_code_r data 63h ;操作反码
;display ctrl ;如果需要释放串口,请用分号后面的脚位
RSPIN EQU P2.7;P1.6
RWPIN EQU P3.0;P1.7
EPIN EQU P3.1;P3.4
LCM_D DATA P0 ;LCM BUS
CHR DATA 61h ;字符码
POS DATA 65h ;显示位置
ir_num data 58h
a_bit data 65h
b_bit data 66h
org CODE_BASE
clr EA
;SETB EA ;打开CPU总中断请求
clr ex0 ;关掉其他中断
clr et1
clr es
clr et0
SETB IT1 ;设定INT1的触发方式为脉冲负边沿触发
SETB EX1 ;打开INT1中断请求 (红外线输入)
mov ir_code,#0ffh
SETB EA ;打开CPU总中断请求
ljmp start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;红外线解码程序 ;
;这部分程序参考了"电子制作实验室"的红外解码程序 ;
;电子制作实验室:Http://www.xie-gang.com ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
INT:
CLR EA ;暂时关闭CPU的所有中断请求
MOV R6,#1
SB:
SJMP YS0 ;转到882微秒延时判断子程序
SBB: ;延时882微秒中判断P3.3脚是否出现高电平如果有就退出解码程序
DJNZ R6, SB ;重复'R6次,目的是检测在8820微秒内如果出现高电平就退出解码程序
;以上完成对遥控信号的9000微秒的初始低电平信号的识别。
JNB P3.3, $ ;等待高电平避开9毫秒低电平引导脉冲
ACALL YS2 ;延时4.74毫秒避开4.5毫秒的结果码
MOV R1,#5CH ;设定1AH为起始RAM区
MOV R2,#4
PP:
MOV R3,#8
JJJJ:
JNB P3.3,$ ;等待地址码第一位的高电平信号
LCALL YS1 ;高电平开始后用882微秒的时间尺去判断信号此时的高低电平状态
MOV C,P3.3 ;将P3.3引脚此时的电平状态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位数据反码,存放在5CH/5DH/5EH/5FH的RAM中
mov a,5fh
cjne a,#0FFh,ir_rec ;跳开#0FFh,如果按时间长,解出的码是#0FFh
sjmp Exit
ir_rec:
mov ir_id_code_r,5dh ;ID反码
mov ir_code_r,5fh ;操作反码
mov ir_code,5eh ;操作原码
mov ir_id_code,5ch ;ID原码
;acall ir_key
EXIT:
SETB EA ;允许中断
call s_code ;显示代码
RETI ;退出解码子程序
YS0:
MOV R4,#220
irD0:
JB P3.3,EXIT
DJNZ R4,irD0
SJMP SBB
YS1:
MOV R4,#20 ;延时子程序1,精确延时882微秒
irD1:
MOV R5,#20
DJNZ R5,$
DJNZ R4,irD1
RET
YS2:
MOV R4,#10 ;延时子程序2,精确延时4740微秒
irD2:
MOV R5,#235
DJNZ R5,$
DJNZ R4,irD2
RET
YS3:
MOV R4,#2 ;延时程序3,精确延时1000微秒
irD3:
MOV R5,#248
DJNZ R5,$
DJNZ R4,irD3
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;LCM Display
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
S_Title:
mov r5,#16 ;字符数
mov a,#00h ;设置DDRAM地址,显示起始位置,00第一行,40第二行
ORL A,#80H ;第8位置1,以符合DDRAM地址设置指令格式
call LCM_COMMAND_00 ;设定DDRAM地址 (显示位置)
mov dptr,#M_Title
mov a,#0
mov r6,#0h
lcall lcm_string ;写一串字符
ret
m_Title:
DB ' ID OC '
s_code:
call s_title ;
call s_spec
call s_ID0 ;
call s_ID1
call s_uc0
call s_uc1
ret
S_spec:
mov r5,#16 ;字符数
mov a,#40h ;设置DDRAM地址,显示起始位置,00第一行,40第二行
ORL A,#80H ;第8位置1,以符合DDRAM地址设置指令格式
call LCM_COMMAND_00 ;设定DDRAM地址 (显示位置)
mov dptr,#M_spec
mov a,#0
mov r6,#0h
lcall lcm_string ;写一串字符
ret
m_spec:
DB ' '
S_ID0:
mov a,#41H ;字符的显示位置
ORL a,#80H ;第8位置1,以符合DDRAM地址设置指令格式
call LCM_COMMAND_00 ;设定DDRAM地址 (显示位置)
mov a,ir_ID_code
call s_num
ret
S_ID1:
mov a,#45H ;字符的显示位置
ORL a,#80H ;第8位置1,以符合DDRAM地址设置指令格式
call LCM_COMMAND_00 ;设定DDRAM地址 (显示位置)
mov a,ir_ID_code_r
call s_num
ret
s_UC0:
mov a,#49H ;字符的显示位置
ORL a,#80H ;第8位置1,以符合DDRAM地址设置指令格式
call LCM_COMMAND_00 ;设定DDRAM地址 (显示位置)
mov a,ir_code
call s_num
ret
s_UC1:
mov a,#4dH ;字符的显示位置
ORL a,#80H ;第8位置1,以符合DDRAM地址设置指令格式
call LCM_COMMAND_00 ;设定DDRAM地址 (显示位置)
mov a,ir_code_r
call s_num
ret
S_num:
mov dptr,#num
call hextohex
mov a,b_bit ;
movc a,@a+dptr
call LCM_COMMAND_10 ;设定DDRAM数据 (显示字符)
mov a,a_bit ;
movc a,@a+dptr
call LCM_COMMAND_10 ;设定DDRAM数据 (显示字符)
ret
num:
DB '0123456789ABCDEF'
S_LOGO:
mov r5,#16 ;字符数
mov a,#40h ;设置DDRAM地址,显示起始位置,00第一行,40第二行
ORL A,#80H ;第8位置1,以符合DDRAM地址设置指令格式
call LCM_COMMAND_00 ;设定DDRAM地址 (显示位置)
mov dptr,#M_logo
mov a,#0
mov r6,#0h
lcall lcm_string ;写一串字符
ret
m_logo:
DB 'www.cdream5.com '
S_LOGO2:
mov r5,#16 ;字符数
mov a,#00h ;设置DDRAM地址,显示起始位置,00第一行,40第二行
ORL A,#80H ;第8位置1,以符合DDRAM地址设置指令格式
call LCM_COMMAND_00 ;设定DDRAM地址 (显示位置)
mov dptr,#M_logo2
mov a,#0
mov r6,#0h
lcall lcm_string ;写一串字符
ret
m_logo2:
DB ' IR Decoder '
S_pls:
mov r5,#16 ;字符数
mov a,#40h ;设置DDRAM地址,显示起始位置,00第一行,40第二行
ORL A,#80H ;第8位置1,以符合DDRAM地址设置指令格式
call LCM_COMMAND_00 ;设定DDRAM地址 (显示位置)
mov dptr,#M_pls
mov a,#0
mov r6,#0h
lcall lcm_string ;写一串字符
ret
m_pls:
DB 'Wait for IR in '
LCM_string:
movc a,@a+dptr
call LCM_COMMAND_10 ;设定DDRAM数据 (显示字符)
dec r5
;call delay_nms ;显示一个字符延时一下,可去掉
cjne r5,#0,tc2 ;若字符显示完,退出
sjmp rrt
tc2:
inc r6 ;下一个字符
mov a,r6
sjmp LCM_string
rrt:
ret
lcd_clr: ;显示清屏
MOV A,#00000001B
CALL LCM_COMMAND_00
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;LCM初始化
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LCM_RESET:
clr ea
CALL DELAY_10MS ;延时30MS
CALL DELAY_10MS
CALL DELAY_10MS
MOV A,#00110000B ;显示模式设置(不检测忙信号)
CALL com00_NO_BF
CALL DELAY_10MS
MOV A,#00110000B ;显示模式设置(不检测忙信号)
CALL com00_NO_BF
CALL DELAY_10MS
MOV A,#00110000B ;显示模式设置(检测忙信号)
CALL LCM_COMMAND_00
MOV A,#00111000B ;显示模式设置(以后均检测忙信号) 8位数据,双行显示,5x7点阵
CALL LCM_COMMAND_00
MOV A,#00001000B ;显示关闭
CALL LCM_COMMAND_00
MOV A,#00000001B ;显示清屏
CALL LCM_COMMAND_00
MOV A,#00001100B ;显示光标移动设置
CALL LCM_COMMAND_00
MOV A,#00000110B ;显示开及光标设置
CALL LCM_COMMAND_00
setb ea
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;送控制指令程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LCM_COMMAND_00: ;送控制指令程序(检测忙信号)
clr ea
CALL BUSY_WAIT
com00_NO_BF: ;送控制字子程序(不检测忙信号)
CLR RSPIN ;RS=0 RW=0
CLR RWPIN
MOV P0,A
NOP
CLR EPIN
NOP
SETB EPIN
setb ea
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;写字符子程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LCM_COMMAND_10: ;写字符子程序
clr ea
CALL BUSY_WAIT
SETB RSPIN ;RS=1 RW=0 E=高脉冲
CLR RWPIN
MOV P0,A
NOP
CLR EPIN
NOP
SETB EPIN
setb ea
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;BF查询子程序 功能: 直到BF=0才退出该程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BUSY_WAIT:
clr ea
PUSH ACC ;保护ACC数据
MOV LCM_D,#0FFH ;将p0口置1
CLR RSPIN ;RS=0
SETB RWPIN ;RW=1
SETB EPIN ;E=高电平
WT_BF:
NOP ;
MOV A,LCM_D
JB ACC.7,WT_BF ;DB7=0 LCD控制器空闲 , DB7=1 LCD控制器忙
POP ACC ;释放ACC数据
setb ea
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;延时程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DELAY_10MS:
MOV R3,#100
DELAY_10MS_L0:
MOV R4,#100
DELAY_10MS_L1:
DJNZ R4,DELAY_10MS_L1
NOP
DJNZ R3,DELAY_10MS_L0
RET
Delay_nms:
MOV r2,#15
delay_2:
call delay_10ms
djnz r2,delay_2
ret
delay_100000us:
mov r7,#0c8h
delay_100000us_l0:
mov r6,#0f8h
delay_100000us_l1:
djnz r6,delay_100000us_l1
nop
djnz r7,delay_100000us_l0
ret
delay:
acall delay_100000us
acall delay_100000us
acall delay_100000us
acall delay_100000us
acall delay_100000us
acall delay_100000us
acall delay_100000us
acall delay_100000us
acall delay_100000us
acall delay_100000us
ret
delay_1000us:
mov r7,#100
delay_1000us_l0:
mov r6,#8
delay_1000us_l1:
djnz r6,delay_1000us_l1
nop
djnz r7,delay_1000us_l0
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;数值分离
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HEXtoHEX:
mov b,#10H ;16进制高位地位分离
div ab
mov b_bit,a ;十位在a
mov a_bit,b ;个位在b
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;程序入口
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:
call lcm_reset
call s_logo
call s_logo2
call delay
loop:
setb ea
jmp $
sjmp loop
db 'Copyright(C)2004 wuwei(cdream5@163.com)'
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -