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

📄 led1sch2.asm

📁 自编的一个遥控码/P0口做4*4键盘扫描,识别.ASM 遥控码和键盘码在串口接8只8字管显示
💻 ASM
字号:
;使用LED1SCH实验板制作摇控区码测试仪,遥控器按下超过3秒(即有重复码)后,8字管显示00000000
;P0口4*4键码测试,在P1口LED上显示2进制,在8字管显示16进制
;开机自检,检查8字管显示是否正常,LED发光二极管是否正常
;2006/03/29
;==================
F_RRPT	BIT	00H		;重复码设置(可重复为"1")
F_CVOK	BIT	01H		;遥控码标志(正常为"1")
F_PRRPT	BIT	02H		;重复码标志(重复为"1")
F_SP	BIT	03H
F_RPT	BIT	04H
F_KSW	BIT	05H
;---------------------
CODE1	EQU	60H		;用户码
CODE2	EQU	61H		;用户码反码
CODE3	EQU	62H		;按键码
CODE4	EQU	63H		;按键码反码

REPTIM	EQU	40H		;重复次数
RPT_1S	EQU	41H		;1秒定时常数
;---------------------
DISP01    EQU   30H
DISP02    EQU   31H
DISP03    EQU   32H
DISP04    EQU   33H
DISP05    EQU   34H
DISP06    EQU   35H
DISP07    EQU   36H
DISP08    EQU   37H
;==============================
        ORg 	0000H
        AJMP 	START    	;转入主程序
        ORG	000BH
        RETI
        ORG	001BH
        RETI
	ORG	0030H
;==============================
START:
	CLR	P3.3
	MOV	R0,#7FH
R_CLR:
	MOV	@R0,#00H
	DJNZ	R0,R_CLR
	MOV     PSW,#00
        CLR     CY
        MOV     SP,#070H
	MOV 	TMOD,#01H
        SETB 	ET0 		;开定时/计数器0允许
        CLR	TR0
	CLR 	EA     		;打开CPU总中断请求
;========================
;开机自检,检查8字管显示是否正常,LED发光二极管是否正常
	MOV	R3,#153
AUTOCAN:
	MOV	CODE1,R3
	MOV	CODE2,R3
	MOV	CODE3,R3
	MOV	CODE4,R3
	LCALL	DIS60H
	LCALL	DELAY
	LCALL	DELAY
	LCALL	DELAY
	LCALL	DELAY
	LCALL	DELAY
	LCALL	DELAY
	CLR	C
	MOV	A,R3
	SUBB	A,#17
	MOV	R3,A
	JNC	AUTOCAN
	LCALL	MUSIC
	MOV	P1,#0FEH
	MOV	R3,#8
RRP1:
	MOV	A,P1
	RR	A
	MOV	P1,A
	LCALL	DELAY
	LCALL	DELAY
	LCALL	DELAY
	LCALL	DELAY
	DJNZ	R3,RRP1
	MOV	P1,#00H
	LCALL	DELAY
	LCALL	DELAY
	LCALL	DELAY
	LCALL	DELAY
	MOV	P1,#0FFH
	SETB	EA
;========================
MAIN:
	JB	P3.2,FEND
	LCALL	REMOPT
	JNB	F_CVOK,FEND
	CLR	F_CVOK
	LCALL	DIS60H
	LCALL	MUSIC
FEND:
	LCALL	KEY
	JNB	F_KSW,NEXT
	CLR	F_KSW
	LCALL	DISKEY
NEXT:
	SJMP	MAIN
;==============================
;键码测试,在P1口LED上显示
;==============================
KEY:
	MOV	A,#00H
	MOV	B,#00H
	MOV 	P0,#0FH 		;P0=0000 1111 用反转法查键
	MOV 	A,P0			;A =0000 1111
	ANL 	A,#0FH			;A =0000 1111
	MOV 	B,A			;B =0000 1111
	MOV 	P0,#0F0H		;P0=1111 0000
	MOV 	A,P0			;A =1111 0000
	ANL 	A,#0F0H			;A =1111 0000
	ORL 	A,B			;A =1111 1111
	CJNE	A,#0FFH,K1
	RET
K1:
	SETB	F_KSW
	CJNE	A,#77H,K2
	MOV	P1,A
	LCALL	MUSIC
	RET
K2:
	CJNE	A,#0B7H,K3
	MOV	P1,A
	LCALL	MUSIC
	RET
K3:
	CJNE	A,#7BH,K4
	MOV	P1,A
	LCALL	MUSIC
	RET
K4:
	CJNE	A,#0BBH,K5
	MOV	P1,A
	LCALL	MUSIC
	RET
K5:
	CJNE	A,#7DH,K6
	MOV	P1,A
	LCALL	MUSIC
	RET
K6:
	CJNE	A,#0BDH,K7
	MOV	P1,A
	LCALL	MUSIC
	RET
K7:
	CJNE	A,#7EH,K8
	MOV	P1,A
	LCALL	MUSIC
	RET
K8:
	CJNE	A,#0BEH,K9
	MOV	P1,A
	LCALL	MUSIC
	RET
K9:
	CJNE	A,#0DEH,K10
	MOV	P1,A
	LCALL	MUSIC
	RET
K10:
	CJNE	A,#0EEH,K11
	MOV	P1,A
	LCALL	MUSIC
	RET
K11:
	CJNE	A,#0DDH,K12
	MOV	P1,A
	LCALL	MUSIC
	RET
K12:
	CJNE	A,#0EDH,K13
	MOV	P1,A
	LCALL	MUSIC
	RET
K13:
	CJNE	A,#0DBH,K14
	MOV	P1,A
	LCALL	MUSIC
	RET
K14:
	CJNE	A,#0EBH,K15
	MOV	P1,A
	LCALL	MUSIC
	RET
K15:
	CJNE	A,#0D7H,K16
	MOV	P1,A
	LCALL	MUSIC
	RET
K16:
	CJNE	A,#0E7H,KEYRET
	MOV	P1,A
	LCALL	MUSIC
	RET
KEYRET:
	RET
;==============================
;检测9ms低电平
REMOPT:
	MOV	TH0,#00H	;初始化计数器
	MOV	TL0,#00H	;初始化计数器
	SETB	TR0		;开始计数
R9msA:
	JB	P3.2,R9msB	;9MS低电平,出现高电平退出
	MOV	A,TH0		;存入低电平时间
	CLR	C		;清进位标示
	SUBB	A,#26H		;计算值与9.728ms比较,
	JC	R9msA		;如果<=9.728MS(进位C=1),则继续检旬高电平出现;
	LJMP	TOERR		;如果>=9.728ms(进位C=0),出错
R9msB:
	MOV	A,TH0		;存入(9MS)低电平时间
	MOV	TH0,#00H	;初始化计数器
	MOV	TL0,#00H	;初始化计数器
	SUBB	A,#20H		;低电平时间与8.192ms比较
	JNC	R4ms5A		;如果>=8.192MS(进位C=0),说明低电平在(8.192MS-9.728MS)内,正常
	LJMP	TOERR		;脉冲间隔<=8.192ms(进位C=1),出错
;---------------------------
;检测4.5ms高电平
R4ms5A:
	JNB	P3.2,R4ms5B	;4.5MS高电平,出现低电平退出
	MOV	A,TH0		;存入低电平时间
	CLR	C		;清进位标示
	SUBB	A,#15H		;计算值与5.376ms比较
	JC	R4ms5A		;如果高电平<=5.376MS(进位C=1),则继续检旬高电平出现;
	LJMP	TOERR		;如果高电平>=5.376ms(进位C=0),出错
R4ms5B:
	MOV	A,TH0		;存入(4.5MS)低电平时间
	MOV	R1,A		;存入(4.5MS)低电平时间
	MOV	TH0,#00H	;初始化计数器
	MOV	TL0,#00H	;初始化计数器
	CLR	C		;清进位标示
	SUBB	A,#10H		;低电平时间与4.096ms比较
	JNC	RCV056ms	;如果>=4.096MS(进位C=0),说明高电平在(4.096MS-5.376MS)内,正常
	LJMP	TORRPT		;脉冲间隔<=4.096ms(进位C=1),看是否为重复码?
;-----------------------------
;检测0.56MS低电平宽度(0.4-0.768MS)
RCV056ms:
	MOV     REPTIM,#0	;(重复码清0)第一个重复码必须计五次才启作用
	MOV	R0,#CODE1	;从CODE1开始,到CODE4结束共4*8=32位
	MOV	R2,#8		;共8位
	MOV	R3,#4		;4个8位
RCV056msA:
	MOV	TH0,#00		;初始化计数器
	MOV	TL0,#00		;初始化计数器
RCV056msB:
	JB	P3.2,RCV056msC	;出现高电平转N1
	MOV	A,TH0		;存入(0.56MS)低电平时间
	CLR	C		;清进位标示
	SUBB	A,#03H		;脉冲间隔<=0.768ms
	JC	RCV056msB	;如果低电平<=0.768MS(进位C=1),则继续检旬高电平出现;
	LJMP	TOERR		;脉冲间隔>=0.768ms
RCV056msC:
	MOV	A,TH0		;存入(0.56MS)低电平时间
	CLR	C		;清进位标示
	SUBB	A,#01H		;脉冲间隔<=0.256ms
	JNC	RCV0768ms	;如果低电平>=0.256MS(进位C=0),说明高电平在(0.256MS-0.768MS)内,正常
	LJMP	TOERR		;脉冲间隔<=0.256ms
RCV0768ms:
	MOV	TH0,#00		;初始化计数器
	MOV	TL0,#00		;初始化计数器
;----------------
;检测0.56MS或1.12MS高电平宽度,如果大于0.768MS为"1"
RCV0768msA:
	JNB	P3.2,RCV0768msB	;出现低电平转RCV0768msB
	MOV	A,TH0		;存入(0.56MS或1.12MS)高电平时间
	CLR	C		;清进位标示
	SUBB	A,#03H		;脉冲间隔<=0.768ms
	JC	RCV0768msA
	JB	P3.2,$		;脉冲间隔>=0.768ms,等待高电平结束
	SETB	C		;C=1 (脉冲间隔>=0.768ms为"1")
	SJMP	RCVHIGH		;该位为"1"
RCV0768msB:
	MOV	A,TH0		;存入(0.56MS)低电平时间
	CLR	C		;清进位标示
	SUBB	A,#01H		;脉冲间隔<=0.256ms
	JNC	RCVLOW		;如果低电平>=0.256MS(进位C=0),说明高电平在(0.256MS-0.768MS)内,正常
	LJMP	TOERR		;脉冲间隔<=0.256ms,出错
RCVLOW:
	CLR	C		;C=0(脉冲间隔<=0.768ms为"0")
RCVHIGH:
	MOV	A,@R0		;A<===@R0
	RRC	A		;A带CY循环右移
	MOV	@R0,A		;@R0<===A
	DJNZ	R2,RCV056msA	;共8位未完继续
	MOV	R2,#8		;共8位
	INC	R0		;指向下一个地止
	DJNZ	R3,RCV056msA	;4个8位未完继续
	MOV	R3,#4		;4个8位
CUSTOK:
        MOV     A,CODE4
        CPL     A
        XRL     A,CODE3
        JNZ     TOERR
CVSOK:
 	SETB	F_CVOK
 	SETB	F_RPT
 	RET
;-----------------------------
TORRPT:				;看是否为重复码(2.5MS)?
	MOV	A,R1
	CLR	C		;清进位标示
	SUBB	A,#0CH		;低电平时间与3.072ms比较
	JC	RRPT1		;如果<=3.072MS,OK
	LJMP	TOERR		;如果>=3.072MS(进位C=0),出错
RRPT1:
	MOV	A,R1
	CLR	C		;清进位标示
	SUBB	A,#08H		;高电平时间与2.048ms比较
	JC	TOERR		;出错
	SETB	F_PRRPT		;说明该脉冲为重复码
RRPT2:
	INC     REPTIM		;重复次数加一
        MOV     A,REPTIM
        CJNE    A,#10H,TOERR	;重复次数未到5次继续
	MOV     REPTIM,#0	;
	SJMP	TOERR1
;------------------------------
TOERR1:
	MOV	CODE1,#00H
	MOV	CODE2,#00H
	MOV	CODE3,#00H
	MOV	CODE4,#00H
	LCALL	DIS60H
	LCALL	MUSIC1
TOERR:
	CLR	F_PRRPT		;清重复码标志
	CLR	F_CVOK		;遥控出错标志
	RET
;==============================
DIS60H:
        MOV 	A,CODE1     	;将存放在RAM\62H中的数据移入A中
        ANL 	A,#0F0H   	;取RAM\62H中的数据低位
        SWAP	 A
        MOV 	R0,#DISP08
        LCALL 	DISNUMA

        MOV 	A,CODE1   	;将存放在RAM\62H中的数据移入A中
        ANL 	A,#0FH    	;取RAM\62H中的数据高位
        MOV 	R0,#DISP07
        LCALL 	DISNUMB
DIS61H:
        MOV 	A,CODE2     	;将存放在RAM\62H中的数据移入A中
        ANL 	A,#0F0H   	;取RAM\62H中的数据低位
        SWAP 	A
        MOV 	R0,#DISP06
        LCALL 	DISNUMA

        MOV 	A,CODE2     	;将存放在RAM\62H中的数据移入A中
        ANL 	A,#0FH    	;取RAM\62H中的数据高位
        MOV 	R0,#DISP05
        LCALL 	DISNUMB
IS62H:
        MOV 	A,CODE3     	;将存放在RAM\62H中的数据移入A中
        ANL 	A,#0F0H   	;取RAM\62H中的数据低位
        SWAP	A
        MOV 	R0,#DISP04
        LCALL	DISNUMA

        MOV 	A,CODE3    	;将存放在RAM\62H中的数据移入A中
        ANL 	A,#0FH    	;取RAM\62H中的数据高位
        MOV 	R0,#DISP03
        LCALL 	DISNUMB
DIS63H:
        MOV 	A,CODE4   	;将存放在RAM\62H中的数据移入A中
        ANL 	A,#0F0H   	;取RAM\62H中的数据低位
        SWAP 	A
        MOV 	R0,#DISP02
        LCALL 	DISNUMA

        MOV 	A,CODE4    	;将存放在RAM\62H中的数据移入A中
        ANL 	A,#0FH    	;取RAM\62H中的数据高位
        MOV 	R0,#DISP01
        LCALL 	DISNUMB
;==============================
;发送子程序
;==============================
LOOP_DISP:
        MOV     R2,#8          ;2个8字显示
        MOV     R0,#DISP01      ;缓冲区首址入R0
        MOV     SCON,#00H       ;UART方式0设定
SOUT:   MOV     A,@R0           ;发送数据入A中
        CLR     TI              ;发送结束标志清零
        MOV     SBUF,A          ;启动发送
	NOP
WAIO:   JNB     TI,WAIO         ;发送等等
        INC     R0              ;指向下一个发送数据地址
        DJNZ    R2,SOUT         ;N个字节发送完未完转SOUT
DISRET:
        RET
;==============================
DISKEY:
        MOV 	DISP08,#11110111B			;前-
        MOV 	DISP07,#11111110B			;后-
        MOV 	DISP06,#10001000B			;前0
        MOV 	A,P1     	;将存放在RAM\62H中的数据移入A中
        ANL 	A,#0FH    	;取RAM\62H中的数据高位
        MOV 	R0,#DISP04
        LCALL 	DISNUMA
        MOV 	A,P1     	;将存放在RAM\62H中的数据移入A中
        ANL 	A,#0F0H   	;取RAM\62H中的数据低位
        SWAP	A
        MOV 	R0,#DISP05
        LCALL	DISNUMB
        MOV 	DISP03,#00110010B			;后H
        MOV 	DISP02,#11110111B			;前-
        MOV 	DISP01,#11111110B			;后-
	SJMP	LOOP_DISP
;==============================
;MOV	@R0,#11110111B			;-

DISNUMA:
DIS0A:					;前0
	CJNE	A,#0,DIS1A
	MOV	@R0,#10001000B		;10001000B
	RET
DIS1A:					;前1
	CJNE	A,#1,DIS2A
	MOV	@R0,#11101110B
	RET
DIS2A:					;前2
	CJNE	A,#2,DIS3A
	MOV	@R0,#10010010B
	RET
DIS3A:					;前3
	CJNE	A,#3,DIS4A
	MOV	@R0,#10100010B
	RET
DIS4A:					;前4
	CJNE	A,#4,DIS5A
	MOV	@R0,#11100100B
	RET
DIS5A:					;前5
	CJNE	A,#5,DIS6A
	MOV	@R0,#10100001B
	RET
DIS6A:					;前6
	CJNE	A,#6,DIS7A
	MOV	@R0,#10000001B
	RET
DIS7A:					;前7
	CJNE	A,#7,DIS8A
	MOV	@R0,#11101010B
	RET
DIS8A:					;前8
	CJNE	A,#8,DIS9A
	MOV	@R0,#10000000B
	RET
DIS9A:					;前9
	CJNE	A,#9,DISA
	MOV	@R0,#10100000B
	RET
DISA:					;前a
	CJNE	A,#0AH,DISB
	MOV	@R0,#11000000B
	RET
DISB:					;前b
	CJNE	A,#0BH,DISC
	MOV	@R0,#10000101B
	RET
DISC:					;前c
	CJNE	A,#0CH,DISD
	MOV	@R0,#10010111B
	RET
DISD:					;前d
	CJNE	A,#0DH,DISE
	MOV	@R0,#10000110B
	RET
DISE:					;前e
	CJNE	A,#0EH,DISF
	MOV	@R0,#10010001b
	RET
DISF:					;前f
	CJNE	A,#0FH,DISARET
	MOV	@R0,#11010001b
	RET
DISARET:
	RET
;==============================
;MOV	@R0,#11111110B			;-
;MOV	@R0,#00110010B			;H
DISNUMB:
DIS0B:					;后0
	CJNE	A,#0,DIS1B
	MOV	@R0,#00010001B		;#00010001B
	RET
DIS1B:					;后1
	CJNE	A,#1,DIS2B
	MOV	@R0,#01110111B		;#01110111B
	RET
DIS2B:					;后2
	CJNE	A,#2,DIS3B
	MOV	@R0,#10010100B
	RET
DIS3B:					;后3
	CJNE	A,#3,DIS4B
	MOV	@R0,#01010100B
	RET
DIS4B:					;后4
	CJNE	A,#4,DIS5B
	MOV	@R0,#01110010B
	RET
DIS5B:					;后5
	CJNE	A,#5,DIS6B
	MOV	@R0,#01011000B
	RET
DIS6B:					;后6
	CJNE	A,#6,DIS7B
	MOV	@R0,#00011000B
	RET
DIS7B:					;后7
	CJNE	A,#7,DIS8B
	MOV	@R0,#01110101B
	RET
DIS8B:					;后8
	CJNE	A,#8,DIS9B
	MOV	@R0,#00010000B
	RET
DIS9B:					;后9
	CJNE	A,#9,DISBA
	MOV	@R0,#01010000B
	RET
DISBA:					;后a
	CJNE	A,#0AH,DISBB
	MOV	@R0,#00110000B
	RET
DISBB:					;后b
	CJNE	A,#0BH,DISBC
	MOV	@R0,#00011010B
	RET
DISBC:					;后C
	CJNE	A,#0CH,DISBD
	MOV	@R0,#10011001B
	RET
DISBD:					;后d
	CJNE	A,#0DH,DISBE
	MOV	@R0,#00010110B
	RET
DISBE:					;后e
	CJNE	A,#0EH,DISBF
	MOV	@R0,#10011000b          ;10011000B
	RET
DISBF:					;后f
	CJNE	A,#0FH,DISBRET
	MOV	@R0,#10111000B
	RET
DISBRET:
	RET

;==============================
MUSIC:
	CPL	P3.3
	LCALL	DELAY
	CPL	P3.3
	RET
;==============================
MUSIC1:
	CPL	P3.3
	LCALL	DELAY
	CPL	P3.3
	LCALL	DELAY
	CPL	P3.3
	LCALL	DELAY
	CPL	P3.3
	RET
;==============================
DELAY:
        MOV     R2,#0FFH
DELAY1: MOV     R1,#0FFH
        DJNZ    R1,$
        DJNZ    R2,DELAY1
        RET
;==============================
	END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -