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

📄 lcm.asm

📁 这是2*8字符型点阵液晶的子程序
💻 ASM
字号:
;LCD模块处理程序
;RWLCDM -- 读写字符型LCD模块
;Input: B.1 -- RS, B.0 -- RW(RW=1 read, RW=0 write)
;       A -- byte want to write into LCD (only available at write mode)
;Output: A -- byte read from LCD (only available at read mode)
;A, PSW not protected
	PROC RWLCDM
RWLCDM:
	CLR EN
	MOV C, B.0
	MOV RW, C		;SET R/W BIT
	MOV C, B.1
	MOV RS, C		;SET REGISTER SELECTION BIT

	MOV PORTL, #0FFH
	SETB EN
	JB B.0, POS1

	MOV PORTL, A		;WRITE TO LCD
	CLR EN
	RET

POS1:	MOV A, PORTL		;READ FROM LCD
	CLR EN
	RET
	END

;DOLCDON -- 开显示
;影响寄存器: A, B, PSW
	PROC DOLCDON
DOLCDON:
	MOV B, #00H
	MOV A, #0CH
	CALL RWLCDM
	CALL WAITBF
	RET
	END

;DOLCDOFF -- 关显示
;影响寄存器: A, B, PSW
	PROC DOLCDOFF
DOLCDOFF:
	MOV B, #00H
	MOV A, #08H
	CALL RWLCDM
	CALL WAITBF
	RET
	END

;DOFUNCREG -- 设置功能寄存器
	PROC DOFUNCREG
DOFUNCREG:
	MOV B, #00H
	MOV A, #38H
	CALL RWLCDM		;置DL为1(8位接口),N=1(2行显示),F=0(5*7点阵)
	RET
	END

;INITLCM -- LCM的上电初始化
	PROC INITLCM
INITLCM:
	MOV R6, #20
	CALL DELAY		;延时20ms

	CALL DOFUNCREG
	MOV R6, #08
	CALL DELAY		;置DL为1并等待8ms

	CALL DOFUNCREG
	MOV R6, #01
	CALL DELAY		;置DL为1并等待1ms

	CALL DOFUNCREG
	CALL WAITBF		;置DL为1

	CALL DOFUNCREG
	CALL WAITBF		;置功能寄存器

	CALL DOLCDOFF		;关显示,关光标,不闪烁

	MOV B, #00H
	MOV A, #01H
	CALL RWLCDM
	CALL WAITBF		;清屏

	MOV B, #00H
	MOV A, #06H
	CALL RWLCDM		;I/D=1, S=0
	CALL WAITBF		;增量方式, 整体显示不移动

	MOV B, #00H
	MOV A, #14H
	CALL RWLCDM		;S/C=0,R/L=1
	CALL WAITBF		;光标移动,右移

	CALL DOLCDON		;开显示

	RET
	END

;WAITBF -- 等待直到BUSY FLAG不忙
;影响寄存器: A, B, PSW
	PROC WAITBF
WAITBF:
	MOV B, #01H		;读状态寄存器
LOOP:	CALL RWLCDM
	JB ACC.7, LOOP
	RET
	END

;DRAWRAM
;将RAM中存放的字符串写入LCDM中
;入口: R1为RAM中字符串起始地址
;      R2为要写入的字符个数, A为LCDM中DDRAM起始地址
;出口: 无
;影响寄存器: A, B, PSW, R1, R2, R3
	PROC DRAWRAM
DRAWRAM:
        MOV R3, A
        MOV B, #00H
        SETB ACC.7
        CALL RWLCDM
        CALL WAITBF                     ;写入DDRAM地址

LPB:    CLR C
        MOV A, R3
        SUBB A, #08H
        JC JPUP
        MOV B, #00H
        MOV A, R3                       ;DDRAM地址大于等于8
        ADD A, #38H
        SETB ACC.7
        CALL RWLCDM
        CALL WAITBF                     ;重新写入DDRAM地址
LPU:    MOV B, #02H
        MOV A, @R1
        CALL RWLCDM
        CALL WAITBF                     ;写入数据
        INC R1
        DJNZ R2, LPU
        RET

JPUP:   MOV B, #02H                     ;DDRAM地址小于8
        MOV A, @R1
        CALL RWLCDM
        CALL WAITBF
        INC R1
        INC R3
        DJNZ R2, LPB
        RET

	END

;DRAWROM
;将ROM中存放的字符串写入LCDM中
;入口: DPTR为ROM中字符串的起始地址
;      R2为要写入的字符个数, A为LCDM中DDRAM起始地址
;出口: 无
;影响寄存器: A, B, PSW, DPTR, R2, R3
	PROC DRAWROM
DRAWROM:
        MOV R3, A
        MOV B, #00H
        SETB ACC.7
        CALL RWLCDM
        CALL WAITBF                     ;写入DDRAM地址

LPB:    CLR C
        MOV A, R3
        SUBB A, #08H
        JC JPUP
        MOV B, #00H
        MOV A, R3                       ;DDRAM地址大于等于8
        ADD A, #38H
        SETB ACC.7
        CALL RWLCDM
        CALL WAITBF                     ;重新写入DDRAM地址
LPU:    MOV B, #02H
        CLR A
        MOVC A, @A+DPTR
        CALL RWLCDM
        CALL WAITBF                     ;写入数据
        INC DPTR
        DJNZ R2, LPU
        RET

JPUP:   MOV B, #02H                     ;DDRAM地址小于8
        CLR A
        MOVC A, @A+DPTR
        CALL RWLCDM
        CALL WAITBF
        INC DPTR
        INC R3
        DJNZ R2, LPB
        RET

	END

;CLEARN -- 将LCM上若干个字符填为某一值
;入口: R2为要清除的字符个数, A为LCM中DDRAM的起始地址, R3为字符
;出口: 无
;影响寄存器: A, B, PSW, R2
	PROC CLEARN
CLEARN:
        CLR C
        SUBB A, #08H
        JC LPU
        ADD A, #40H
        SJMP PROS
LPU:    ADD A, #08H
PROS:	MOV B, #00H		;写指令寄存器
	SETB ACC.7
	CALL RWLCDM
	CALL WAITBF
LOOP:	MOV B, #02H		;写数据寄存器
	MOV A, R3		;空格
	CALL RWLCDM
	CALL WAITBF
	DJNZ R2, LOOP
	RET
	END

;FILLDISPBUF
;将16位二进制数转为4位十进制ASCII码数, 并填入显示缓冲区中
;入口: R0指向要转换的16位二进制字, R1指向显示缓冲区
;出口: @R1为显示缓冲区, 不保留原16位数(@R0)
;影响寄存器: B, R2, PSW, DSPNEG, @R0, R3
	PROC FILLDISPBUF
FILLDISPBUF:
	INC R0
	MOV A, @R0
	DEC R0
	MOV C, ACC.7
	MOV DSPNEG, C		;取符号位
	JNC TP1
	CALL NEG16		;如果是负数则求补

TP1:    MOV A, #0AH
        CALL DIV16_4

        JNB DSPNEG, FTP1
        MOV CTEMP, #LOW(100)
        MOV CTEMP+1, #HIGH(100)
        JMP FTP2
FTP1:   MOV CTEMP, #LOW(1000)
        MOV CTEMP+1, #HIGH(1000)
FTP2:   MOV A, R1
        MOV R3, A
        MOV R1, #CTEMP
        CALL CMPR0R1
        MOV A, R3
        MOV R1, A
        JC FTP3

        INC R1                   ;有小数点
        INC R1
        INC R1
        MOV A, #0AH
        CALL DIV16_4
        ADD A, #30H
        MOV @R1, A
        DEC R1
        MOV @R1, #2EH
        DEC R1

	MOV R3, #02H
LOOP2:	MOV A, #0AH
	CALL DIV16_4
	ADD A, #30H
	MOV @R1, A
	DEC R1
	DJNZ R3, LOOP2		;将3位原码填入缓冲区
        INC R1
        JNB DSPNEG, TTP3
        MOV @R1, #2DH
        RET
TTP3:   CJNE @R1, #30H, TTP4
        MOV @R1, #20H
TTP4:   RET

FTP3:                            ;无小数点
        MOV A, #0AH
        CALL DIV16_4

	INC R1
	INC R1
	INC R1
	MOV R3, #03H
LOOP1:	MOV A, #0AH
	CALL DIV16_4
	ADD A, #30H
	MOV @R1, A
	DEC R1
	DJNZ R3, LOOP1		;将3位原码填入缓冲区

        JNB DSPNEG, TTP1
        INC R1
        CJNE @R1, #30H, TTP2
        MOV @R1, #2DH
        DEC R1
TTP1:   MOV @R1, #20H
        RET
TTP2:   DEC R1
        MOV @R1, #2DH
        RET

	END

⌨️ 快捷键说明

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