📄 lcm.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 + -