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

📄 12864.asm

📁 2005年全国大学生电子设计竞赛论文集
💻 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 + -