📄 12864.asm
字号:
//////////////////////////////////////////////////////////////////////////////////////////////////////
// 12864 点阵液晶驱动程序 V1.4(数据压缩版2) for 凌阳SPCE061A
// 12864 纵向取模,字节倒序
// DB0~7接IOB8~16 DI-IOB5,RW-IOB6,E-IOB7, CS1-IOB4, CS2-IOB3
// IDE 环境 SPIDE1.16.1
// 2005年8月30日
// 浙江大学 徐 进
//////////////////////////////////////////////////////////////////////////////////////////////////////
.include hardware.inc
.RAM
.VAR LCD_CS //CS片选,CS=0时选择芯片1,CS=1时选择芯片2
.PUBLIC _LCD_LINE
.VAR _LCD_LINE //起始行
.PUBLIC _LCD_PAGE
.VAR _LCD_PAGE //页
.PUBLIC _LCD_Y
.VAR _LCD_Y //列
.PUBLIC _ADDR
.VAR _ADDR
.VAR _LCD_HIGH
.VAR _LCD_INPUT_LENGTH
.VAR _LCD_Y_O
.VAR _Sellect
.VAR Input_Data_Bit
.VAR Input_Data
.CODE
//==========================================================================================================
//LCD端口初始化
//==========================================================================================================
.PUBLIC _LCD_Ini
_LCD_Ini: .proc
R1=0xFFF8 //设置端口属性为同相输出
[P_IOB_Dir]=R1
[P_IOB_Attrib]=R1
RETF
.ENDP
//==========================================================================================================
//==========================================================================================================
//清屏
//==========================================================================================================
.PUBLIC _LCD_CLEAR
_LCD_CLEAR: .PROC
PUSH R1,R5 TO [SP]
R1=0x0000
[_LCD_LINE]=R1
[_LCD_PAGE]=R1
[_LCD_Y]=R1
[LCD_CS]=R1
CALL _LCD_OPEN
CALL _LCD_SET_LINE
CALL _LCD_SET_PAGE
CALL _LCD_SET_Y
R1=0x0000
CALL _LCD_TEST
R1=1
[LCD_CS]=R1
CALL _LCD_OPEN
CALL _LCD_SET_LINE
CALL _LCD_SET_PAGE
CALL _LCD_SET_Y
R1=0x0000
CALL _LCD_TEST
POP R1,R5 FROM [SP]
RETF
_LCD_TEST:
PUSH R2,R5 TO [SP]
JMP T_LOOP
T_LOOP2:
R3=[_LCD_PAGE]
R3+=1
[_LCD_PAGE]=R3
T_LOOP:
CALL _LCD_SET_PAGE
R2=0x0040
T_LOOP1:
CALL _LCDWRDATA
R2-=1
CMP R2,0x0000
JNE T_LOOP1
CMP R3,0x0007
JNE T_LOOP2
R2=0x0000
[_LCD_LINE]=R2
CALL _LCD_SET_LINE
[_LCD_PAGE]=R2
CALL _LCD_SET_PAGE
[_LCD_Y]=R2
CALL _LCD_SET_Y
POP R2,R5 FROM [SP]
RETF
.ENDP
//==========================================================================================================
//清除下半屏报警内容
//==========================================================================================================
.PUBLIC _LCD_Clr_half
_LCD_Clr_half: .proc
PUSH R1,R5 TO [SP]
r1=0x0000
[_LCD_LINE]=R1
[_LCD_Y]=R1
[LCD_CS]=R1
r1=0x0004
[_LCD_PAGE]=R1
CALL _LCD_OPEN
CALL _LCD_SET_LINE
CALL _LCD_SET_PAGE
CALL _LCD_SET_Y
R1=0x0000
CALL _LCD_TEST
R1=1
[LCD_CS]=R1
r1=4
[_LCD_PAGE]=R1
CALL _LCD_OPEN
CALL _LCD_SET_LINE
CALL _LCD_SET_PAGE
CALL _LCD_SET_Y
R1=0x0000
CALL _LCD_TEST
POP R1,R5 FROM [SP]
RETF
.endp
//==========================================================================================================
//==========================================================================================================
//写入半屏数据
//传入参数2个,依次为CS和显示表地址,传入参数CS为0时选择左半屏,传入参数为0时为左半屏,传入参数为1时为右半屏
//函数无返回值
//==========================================================================================================
.PUBLIC _WRITE_HALF
_WRITE_HALF: .PROC
PUSH R1,R5 TO [SP]
BP=SP+5
R1=[BP+3]
[LCD_CS]=R1
R1=[BP+4]
[_ADDR]=R1
R1=0x0000
[_LCD_LINE]=R1
[_LCD_PAGE]=R1
[_LCD_Y]=R1
[Input_Data_Bit]=R1
CALL _LCD_OPEN
CALL _LCD_SET_LINE
CALL _LCD_SET_PAGE
CALL _LCD_SET_Y
R4=0x0000
JMP W_LOOP
W_LOOP2:
R3=[_LCD_PAGE]
R3+=1
[_LCD_PAGE]=R3
W_LOOP:
CALL _LCD_SET_PAGE
R2=0x0040
W_LOOP1:
R1=[Input_Data_Bit]
CMP R1,0x0000
JNE Data_Low1
R1=1
[Input_Data_Bit]=R1
BP=[_ADDR]
BP+=R4
R4+=1
R1=[BP]
R1|=0xFF00
R1-=0xFF00
[Input_Data]=R1
R1=[BP]
R1=R1 LSR 4
R1=R1 LSR 4
JMP INPUT1
Data_Low1:
R1=0
[Input_Data_Bit]=R1
R1=[Input_Data]
INPUT1:
R1=R1 LSL 4
R1=R1 LSL 4
CALL _LCDWRDATA
R1 = 0x0001; //清看门狗
[P_Watchdog_Clear]=R1;
R2-=1
CMP R2,0x0000
JNE W_LOOP1
CMP R3,0x0007
JNE W_LOOP2
POP R1,R5 FROM [SP]
RETF
.ENDP
//=========================================================================================================
//=========================================================================================================
//写入整屏数据
//传入参数为显示表地址
//函数无返回值
//=========================================================================================================
.PUBLIC _INPUT_ALL_SCREEN
_INPUT_ALL_SCREEN: .PROC //接口程序,写入整屏数据
PUSH R1,R5 TO [SP]
BP=SP+5
R1=[BP+3]
[_ADDR]=R1
R1=0
[LCD_CS]=R1
[_LCD_LINE]=R1
[_LCD_PAGE]=R1
[_LCD_Y]=R1
[Input_Data_Bit]=R1
CALL _LCD_OPEN
CALL _LCD_SET_LINE
CALL _LCD_SET_PAGE
CALL _LCD_SET_Y
R4=0x0000
JMP AS_LOOP_L
AS_LOOP2:
R1=0
[LCD_CS]=R1
[_LCD_LINE]=R1
[_LCD_Y]=R1
CALL _LCD_OPEN
CALL _LCD_SET_LINE
CALL _LCD_SET_Y
R3=[_LCD_PAGE]
R3+=1
[_LCD_PAGE]=R3
AS_LOOP_L:
CALL _LCD_SET_PAGE
R2=0x0040
AS_LOOP1:
R1=[Input_Data_Bit]
CMP R1,0x0000
JNE Data_Low2
R1=1
[Input_Data_Bit]=R1
BP=[_ADDR]
BP+=R4
R4+=1
R1=[BP]
R1|=0xFF00
R1-=0xFF00
[Input_Data]=R1
R1=[BP]
R1=R1 LSR 4
R1=R1 LSR 4
JMP INPUT2
Data_Low2:
R1=0
[Input_Data_Bit]=R1
R1=[Input_Data]
INPUT2:
R1=R1 LSL 4
R1=R1 LSL 4
CALL _LCDWRDATA
R2-=1
CMP R2,0x0000
JNE AS_LOOP1
AS_LOOP_R:
R1=1
[LCD_CS]=R1
R1=0
[_LCD_LINE]=R1
[_LCD_Y]=R1
CALL _LCD_SET_LINE
CALL _LCD_SET_PAGE
CALL _LCD_SET_Y
R2=0x0040
AS_LOOP3:
R1=[Input_Data_Bit]
CMP R1,0x0000
JNE Data_Low3
R1=1
[Input_Data_Bit]=R1
BP=[_ADDR]
BP+=R4
R4+=1
R1=[BP]
R1|=0xFF00
R1-=0xFF00
[Input_Data]=R1
R1=[BP]
R1=R1 LSR 4
R1=R1 LSR 4
JMP INPUT3
Data_Low3:
R1=0
[Input_Data_Bit]=R1
R1=[Input_Data]
INPUT3:
R1=R1 LSL 4
R1=R1 LSL 4
CALL _LCDWRDATA
R2-=1
CMP R2,0x0000
JNE AS_LOOP3
R3=[_LCD_PAGE]
CMP R3,0x0007
JNE INPUT_L
POP R1,R5 FROM [SP]
RETF
INPUT_L:
GOTO AS_LOOP2
.ENDP
//==========================================================================================================
//==========================================================================================================
//LCD写入特定数据,指定起始页,列,数据宽度
// 如:起始为第3页,第5列,120x15中的宽度为120。其中列数加长度小于等于128
// Sel项:0,正常写入; 1,取反写入。
//传入参数5个,依次为Sel项,页数(0~7),列数(0~127),宽度(1~128),高度, 显示表地址
//==========================================================================================================
.PUBLIC _LCD_INPUT
_LCD_INPUT: .PROC
PUSH R1,R5 TO [SP]
BP=SP+5
R1=[BP+3]
[_Sellect]=R1
R1=[BP+4]
[_LCD_PAGE]=R1
R1=[BP+5]
[_LCD_Y]=R1
[_LCD_Y_O]=R1
R1=[BP+6]
[_LCD_INPUT_LENGTH]=R1
R1=[BP+7]
[_LCD_HIGH]=R1
R1=[BP+8]
[_ADDR]=R1
R1=0
[Input_Data_Bit]=R1
R1=[_LCD_Y]
CMP R1,0x003F
JBE CHOSE_CS1
R1=1
[LCD_CS]=R1
R1=[_LCD_Y]
R1-=0x003F
[_LCD_Y]=R1
JMP SET_LCD
CHOSE_CS1:
R1=0
[LCD_CS]=R1
SET_LCD:
CALL _LCD_OPEN
CALL _LCD_SET_Y
CALL _LCD_SET_PAGE
R4=0x0000
R2=0
R3=[_LCD_Y]
LOOP_INPUT1:
R1=[Input_Data_Bit]
CMP R1,0x0000
JNE Data_Low4
R1=1
[Input_Data_Bit]=R1
BP=[_ADDR]
BP+=R4
R1=[BP]
R4+=1
R1|=0xFF00
R1-=0xFF00
[Input_Data]=R1
R1=[BP]
R1=R1 LSR 4
R1=R1 LSR 4
JMP INPUT4
Data_Low4:
R1=0
[Input_Data_Bit]=R1
R1=[Input_Data]
INPUT4:
R2+=1
PUSH R1 TO [SP]
R1=[_Sellect]
CMP R1,0x0001
JE OPP1
POP R1 FROM [SP]
R1=R1 LSL 4
R1=R1 LSL 4
JMP SHOW1
OPP1:POP R1 FROM [SP]
R1^=0x00FF
R1=R1 LSL 4
R1=R1 LSL 4
SHOW1:
CALL _LCDWRDATA
R3+=1
R1=[_LCD_INPUT_LENGTH]
CMP R1,R2
JE INPUT_PAGE_OVER
CMP R3,0x003F
JBE LOOP_INPUT1
R1=1
[LCD_CS]=R1
R1=0
[_LCD_Y]=R1
CALL _LCD_SET_Y
CALL _LCD_SET_PAGE
INPUT_LOOP2:
R1=[Input_Data_Bit]
CMP R1,0x0000
JNE Data_Low5
R1=1
[Input_Data_Bit]=R1
BP=[_ADDR]
BP+=R4
R1=[BP]
R4+=1
R1|=0xFF00
R1-=0xFF00
[Input_Data]=R1
R1=[BP]
R1=R1 LSR 4
R1=R1 LSR 4
JMP INPUT5
Data_Low5:
R1=0
[Input_Data_Bit]=R1
R1=[Input_Data]
INPUT5:
R2+=1
PUSH R1 TO [SP]
R1=[_Sellect]
CMP R1,0x0001
JE OPP2
POP R1 FROM [SP]
R1=R1 LSL 4
R1=R1 LSL 4
JMP SHOW2
OPP2:
POP R1 FROM [SP]
R1^=0x00FF
R1=R1 LSL 4
R1=R1 LSL 4
SHOW2:
CALL _LCDWRDATA
R1=[_LCD_INPUT_LENGTH]
CMP R1,R2
JE INPUT_PAGE_OVER
JMP INPUT_LOOP2
INPUT_OVER:
POP R1,R5 FROM [SP]
RETF
INPUT_PAGE_OVER:
R1=[_LCD_HIGH]
CMP R1,8
JA NOTOVER
JMP INPUT_OVER
NOTOVER:
R1-=8
[_LCD_HIGH]=R1
R1=[_LCD_PAGE]
R1+=1
[_LCD_PAGE]=R1
R1=[_LCD_Y_O]
[_LCD_Y]=R1
CMP R1,0x003F
JBE CHOSE_CS1_NP
R1=1
[LCD_CS]=R1
R1=[_LCD_Y]
R1-=0x003F
[_LCD_Y]=R1
JMP SET_LCD_NP
CHOSE_CS1_NP:
R1=0
[LCD_CS]=R1
SET_LCD_NP:
CALL _LCD_SET_Y
CALL _LCD_SET_PAGE
R3=[_LCD_Y]
R2=0
GOTO LOOP_INPUT1
RETF
.ENDP
//==========================================================================================================
//==========================================================================================================
//LCD滚屏函数
//==========================================================================================================
.PUBLIC _LCD_MOVE
_LCD_MOVE: .PROC
PUSH R1,R5 TO [SP]
R1=0x0000
_LCD_MOVE_LOOP:
[_LCD_LINE]=R1
R2=0
[LCD_CS]=R2
CALL _LCD_SET_LINE
R2=1
[LCD_CS]=R2
CALL _LCD_SET_LINE
CALL _LCD_MOVE_DELAY
R1+=1
CMP R1,0x003F
JNE _LCD_MOVE_LOOP
R1=0x0000
JMP _LCD_MOVE_LOOP
POP R1,R5 FROM [SP]
RETF
.ENDP
.PUBLIC _LCD_MOVE_DELAY
_LCD_MOVE_DELAY: .PROC
PUSH R1,R5 TO [SP]
R1=0x8FFF
_MOVE_LOOP:
R4 = 0x0001; //清看门狗
[P_Watchdog_Clear]=R4;
R1-=1
CMP R1,0x0000
JNE _MOVE_LOOP
POP R1,R5 FROM [SP]
RETF
.ENDP
//==========================================================================================================
//==========================================================================================================
//LCD启动,开显示
//==========================================================================================================
_LCD_OPEN:
PUSH R1,R5 TO [SP]
R1=0x3F00
CALL _LCDWRST
POP R1,R5 FROM [SP]
RETF
//==========================================================================================================
//==========================================================================================================
//LCD起始行设定
//==========================================================================================================
_LCD_SET_LINE:
PUSH R1,R5 TO [SP]
R1=[_LCD_LINE]
R1|=0x00c0
R1=R1 LSL 4
R1=R1 LSL 4
CALL _LCDWRST
POP R1,R5 FROM [SP]
RETF
//==========================================================================================================
//==========================================================================================================
//LCD页设定
//==========================================================================================================
_LCD_SET_PAGE:
PUSH R1,R5 TO [SP]
R1=[_LCD_PAGE]
R1|=0x00B8
R1=R1 LSL 4
R1=R1 LSL 4
CALL _LCDWRST
POP R1,R5 FROM [SP]
RETF
//==========================================================================================================
//==========================================================================================================
//LCD列设定
//==========================================================================================================
_LCD_SET_Y:
PUSH R1,R5 TO [SP]
R1=[_LCD_Y]
R1|=0x0040
R1=R1 LSL 4
R1=R1 LSL 4
CALL _LCDWRST
POP R1,R5 FROM [SP]
RETF
//==========================================================================================================
//==========================================================================================================
//LCD写入控制命令
//==========================================================================================================
_LCDWRST:
PUSH R2,R5 TO [SP]
PUSH R1 TO [SP]
CALL DELAY
POP R1 FROM [SP]
R2=[LCD_CS]
CMP R2,0x0000
JE CHOSE_CS1_ST
JMP CHOSE_CS2_ST
CHOSE_CS1_ST:
R2=0x0010
[P_IOB_Data]=R2
R2=0x0090
R2+=R1
[P_IOB_Data]=R2
R2=0x0010
R2+=R1
[P_IOB_Data]=R2
R2=0x0060
[P_IOB_Data]=R2
POP R2,R5 FROM [SP]
RETF
CHOSE_CS2_ST:
R2=0x0008
[P_IOB_Data]=R2
R2=0x0088
R2+=R1
[P_IOB_Data]=R2
R2=0x0008
R2+=R1
[P_IOB_Data]=R2
R2=0x0060
[P_IOB_Data]=R2
POP R2,R5 FROM [SP]
RETF
//==========================================================================================================
//==========================================================================================================
//LCD写入数据
//==========================================================================================================
_LCDWRDATA:
PUSH R2,R5 TO [SP]
PUSH R1 TO [SP]
CALL DELAY
POP R1 FROM [SP]
R2=[LCD_CS]
CMP R2,0x0000
JE CHOSE_CS1_DATA
JMP CHOSE_CS2_DATA
CHOSE_CS1_DATA:
R2=0x0030
[P_IOB_Data]=R2
R2=0x00B0
R2+=R1
[P_IOB_Data]=R2
R2=0x0030
R2+=R1
[P_IOB_Data]=R2
R2=0x0060
[P_IOB_Data]=R2
POP R2,R5 FROM [SP]
RETF
CHOSE_CS2_DATA:
R2=0x0028
[P_IOB_Data]=R2
R2=0x00A8
R2+=R1
[P_IOB_Data]=R2
R2=0x0028
R2+=R1
[P_IOB_Data]=R2
R2=0x0060
[P_IOB_Data]=R2
POP R2,R5 FROM [SP]
RETF
//===========================================================================================================
//===========================================================================================================
//LCD忙查询
//===========================================================================================================
DELAY:
R1=0x00F8 //改变IO口属性,设置为输入
[P_IOB_Dir]=R1
[P_IOB_Attrib]=R1
R2=[LCD_CS]
CMP R2,0x0000
JE CHOSE_CS1_DELAY
JMP CHOSE_CS2_DELAY
CHOSE_CS1_DELAY:
R1=0xFF50
[P_IOB_Data]=R1
R1=0xFFD0
[P_IOB_Data]=R1
JMP INDELAY
CHOSE_CS2_DELAY:
R1=0xFF48
[P_IOB_Data]=R1
R1=0xFFC8
[P_IOB_Data]=R1
INDELAY:
R2=[P_IOB_Data]
R1=0x0000
[P_IOB_Data]=R1
R4 = 0x0001; //清看门狗
[P_Watchdog_Clear]=R4;
R2|=0x7fff;
R2-=0x7fff;
test R2,0x8000;
JNZ DELAY;
R1=0xFFF8 //重新设定IO口为同相输出
[P_IOB_Dir]=R1
[P_IOB_Attrib]=R1
RETF
//===========================================================================================================
.END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -