?? 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 + -