⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ir_decoder.asm

📁 红外线遥控解码器,该程序实现将红外遥控器发出的红外线解码
💻 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 + -