|||
这是我以前发表在PIC16论坛的一段代码;
;****************************************************************************
;Filename:TestLCD.asm
;Programmer:资道周
;Creat Time:2006-01-07 15:23
;Modify Time:2006-02-23 10:40
;Description:This is a test for LCD
; 硬件连接关系:
; MCU(PIC16F648A) LCD(24064,T6963)
; RA0------------------------WR
; RA1------------------------RD
; RA2------------------------CD
; RB0------------------------D0
; RB1------------------------D1
; RB2------------------------D2
; RB3------------------------D3
; RB4------------------------D4
; RB5------------------------D5
; RB6------------------------D6
; RB7------------------------D7
; CE-----------------GND
; 程序显示内容:在液晶屏坐标(4,1)开始负向显示"THIS IS A TEST!".
; 在液晶屏坐标(4,2)开始闪烁显示"THIS IS A TEST!".
; 在液晶屏坐标(19,3)开始负向闪烁显示汉字"资道周"
; 在液晶屏坐标(19,5)开始正向显示汉字"资道周"
;****************************************************************************
#include
TEMP1 EQU 0x20
DAT1 EQU 0x21
DAT2 EQU 0x22
COM EQU 0x23
X EQU 0x24
Y EQU 0x25
CODEA EQU 0x26
ATTR EQU 0x27
PARA1 EQU 0x28
PARA2 EQU 0x29
COUNT EQU 0x2A
RESULT_L EQU 0x2B
RESULT_H EQU 0x2C
COUNT1 EQU 0x2D
CNT EQU 0x2E
CT_CODE EQU 0x2F
TEMP2 EQU 0x30
TEMP3 EQU 0x31
TEMP4 EQU 0x32
TEMP5 EQU 0x33
TEMP6 EQU 0x34
ORG 0x00
GOTO MAIN
ORG 0x04
GOTO INT_SERVICE
ORG 0x1C
TABLE_1:
MOVF COUNT1,W
ADDWF PCL,F
RETLW 0x41
RETLW 0x21
RETLW 0x23
RETLW 0x14
RETLW 0xE8
RETLW 0x41
RETLW 0x46
RETLW 0x5F
RETLW 0x10
RETLW 0x11
RETLW 0x11
RETLW 0x11
RETLW 0x12
RETLW 0x04
RETLW 0x18
RETLW 0x60
RETLW 0x00
RETLW 0x00
RETLW 0xFC
RETLW 0x58
RETLW 0x40
RETLW 0xA0
RETLW 0x18
RETLW 0xF6
RETLW 0x10
RETLW 0x10
RETLW 0x10
RETLW 0x10
RETLW 0xC0
RETLW 0x30
RETLW 0x1C
RETLW 0x08 ;"资"的字符码,80H
RETLW 0x02
RETLW 0x41
RETLW 0x2F
RETLW 0x20
RETLW 0x01
RETLW 0x03
RETLW 0xE2
RETLW 0x23
RETLW 0x22
RETLW 0x23
RETLW 0x22
RETLW 0x23
RETLW 0x22
RETLW 0x50
RETLW 0x8F
RETLW 0x00
RETLW 0x10
RETLW 0x20
RETLW 0xFC
RETLW 0x80
RETLW 0x00
RETLW 0xF0
RETLW 0x10
RETLW 0xF0
RETLW 0x10
RETLW 0xF0
RETLW 0x10
RETLW 0xF0
RETLW 0x10
RETLW 0x00
RETLW 0xFE
RETLW 0x00 ;"道"的字符码,84H
RETLW 0x00
RETLW 0x1F
RETLW 0x10
RETLW 0x13
RETLW 0x10
RETLW 0x10
RETLW 0x17
RETLW 0x10
RETLW 0x13
RETLW 0x12
RETLW 0x12
RETLW 0x13
RETLW 0x22
RETLW 0x20
RETLW 0x40
RETLW 0x80
RETLW 0x00
RETLW 0xFC
RETLW 0x84
RETLW 0xE4
RETLW 0x84
RETLW 0x84
RETLW 0xF4
RETLW 0x04
RETLW 0xE4
RETLW 0x24
RETLW 0x24
RETLW 0xE4
RETLW 0x24
RETLW 0x04
RETLW 0x14
RETLW 0x08 ;"周"的字符码,88H
MAIN:
CALL INITMCU ;cpu初始化
MOVLW 0x08 ; 显示光标在(8,0)
MOVWF DAT1
MOVLW 0x00
MOVWF DAT2
MOVLW 0x21
MOVWF COM
CALL PR1
MOVLW 0x04
MOVWF X
MOVLW 0x01
MOVWF Y
MOVLW 'T'-0x20 ;显示"T"在(4,1)
MOVWF CODEA
MOVLW 0x05
MOVWF ATTR
CALL WRT_C
INCF X,F
MOVLW 'H'-0x20 ;显示"H"在(5,1)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'I'-0x20 ;显示"I"在(6,1)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'S'-0x20 ;显示"S"在(7,1)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW ' '-0x20 ;显示" "在(8,1)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'I'-0x20 ;显示"I"在(9,1)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'S'-0x20 ;显示"S"在(10,1)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW ' '-0x20 ;显示" "在(11,1)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'A'-0x20 ;显示"A"在(12,1)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW ' '-0x20 ;显示" "在(13,1)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'T'-0x20 ;显示"T"在(14,1)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'E'-0x20 ;显示"E"在(15,1)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'S'-0x20 ;显示"S"在(16,1)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'T'-0x20 ;显示"T"在(17,1)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW '!'-0x20 ;显示"!"在(18,1)
MOVWF CODEA
CALL WRT_C
MOVLW 0x04
MOVWF X
MOVLW 0x02
MOVWF Y
MOVLW 'T'-0x20 ;显示"T"在(4,2)
MOVWF CODEA
MOVLW 0x08
MOVWF ATTR
CALL WRT_C
INCF X,F
MOVLW 'H'-0x20 ;显示"H"在(5,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'I'-0x20 ;显示"I"在(6,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'S'-0x20 ;显示"S"在(7,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW ' '-0x20 ;显示" "在(8,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'I'-0x20 ;显示"I"在(9,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'S'-0x20 ;显示"S"在(10,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW ' '-0x20 ;显示" "在(11,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'A'-0x20 ;显示"A"在(12,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW ' '-0x20 ;显示" "在(13,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'T'-0x20 ;显示"T"在(14,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'E'-0x20 ;显示"E"在(15,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'S'-0x20 ;显示"S"在(16,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW 'T'-0x20 ;显示"T"在(17,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
MOVLW '!'-0x20 ;显示"!"在(18,2)
MOVWF CODEA
CALL WRT_C
INCF X,F
INCF Y,F
MOVLW 0x80
MOVWF CT_CODE
MOVLW B'00001101'
MOVWF ATTR
CALL WRT_CT ;显示"资"在(19,3)
INCF X,F
INCF X,F
MOVLW 0x84
MOVWF CT_CODE
CALL WRT_CT ;显示"道"在(21,3)
INCF X,F
INCF X,F
MOVLW 0x88
MOVWF CT_CODE
CALL WRT_CT ;显示"周"在(23,3)
INCF Y,F
INCF Y,F
MOVLW 0X04
SUBWF X,F
MOVLW 0x80
MOVWF CT_CODE
MOVLW 0X00
MOVWF ATTR
CALL WRT_CT ;显示"资"在(19,5)
INCF X,F
INCF X,F
MOVLW 0x84
MOVWF CT_CODE
CALL WRT_CT ;显示"道"在(21,5)
INCF X,F
INCF X,F
MOVLW 0x88
MOVWF CT_CODE
CALL WRT_CT ;显示"周"在(23,5)
LOOP:
GOTO LOOP
INITMCU:
CLRF PORTA ;清A口
CLRF PORTB ;清B口
MOVLW 0x07
MOVWF CMCON
CALL INITLCD ;液晶显示器初始化
CALL CLEAR
MOVLW 0x03 ;建立三个汉字的汉字库
MOVWF CNT
CALL CGRAM
RETURN
;==================液晶初始化程序==========================
INITLCD:
MOVLW 0x00
MOVWF DAT1
MOVLW 0x00
MOVWF DAT2
MOVLW 0x40
MOVWF COM
CALL PR1 ;设置文本显示区地址,首地址为0x00
MOVLW 0x1E
MOVWF DAT1
MOVLW 0x00
MOVWF DAT2
MOVLW 0x41
MOVWF COM
CALL PR1 ;设置文本显示区域宽度为30个字节
MOVLW 0x00
MOVWF DAT1
MOVLW 0x0C
MOVWF DAT2
MOVLW 0x42
MOVWF COM
CALL PR1 ;设置文本属性区首地址
MOVLW 0x1E
MOVWF DAT1
MOVLW 0x00
MOVWF DAT2
MOVLW 0x43
MOVWF COM
CALL PR1 ;设置文本显示区域宽度为30个字节
MOVLW 0xA0
MOVWF COM
CALL PR12 ;设置光标形状为1*8
MOVLW 0x84
MOVWF COM
CALL PR12 ;设置显示方式为文本属性方式
MOVLW 0x9F
MOVWF COM
CALL PR12 ;设置开关显示,开文本显示和光标显示
RETURN
;==========液晶屏写指令子程序===============================
PR1: ;双参数子程序入口
BSF STATUS,RP0 ;SET TO BANK1
MOVLW 0x00 ;PORTA SET TO OUTPUT
MOVWF TRISA
MOVLW 0xFF ;PORTB SET TO INPUT
MOVWF TRISB
BCF STATUS,RP0 ;SET BACK TO BANK0
MOVLW 0x04
IORWF PORTA,F ;SET CD
MOVLW 0xFD
ANDWF PORTA,F ;CLR RD
MOVF PORTB,W ;READ PORTB
MOVWF TEMP1
MOVLW 0x02
IORWF PORTA,F ;SET RD
BTFSS TEMP1,0x00 ;JUDGE PORTB.0,IF!=0,READ AGAIN,ELSE GO ON
GOTO PR1
BTFSS TEMP1,0x01 ;JUDGE PORTB.1,IF!=0,READ AGAIN,ELSE GO ON
GOTO PR1
BSF STATUS,RP0 ;SET TO BANK1
MOVLW 0x00 ;PORTB SET TO OUTPUT
MOVWF TRISB
BCF STATUS,RP0 ;SET BACK TO BANK0
MOVLW 0xFB ;CLR CD
ANDWF PORTA,F
MOVF DAT1,W ;WRITE DAT1 TO PORTB
MOVWF PORTB
MOVLW 0xFE ;CLR WR
ANDWF PORTA,F
MOVLW 0x01 ;SET WR
IORWF PORTA,F
PR11: ;单参数子程序入口
BSF STATUS,RP0 ;SET TO BANK1
MOVLW 0x00 ;PORTA SET TO OUTPUT
MOVWF TRISA
MOVLW 0xFF ;PORTB SET TO INPUT
MOVWF TRISB
BCF STATUS,RP0 ;SET BACK TO BANK0
MOVLW 0x04
IORWF PORTA,F ;SET CD
MOVLW 0xFD
ANDWF PORTA,F ;CLR RD
MOVF PORTB,W ;READ PORTB
MOVWF TEMP1
MOVLW 0x02
IORWF PORTA,F ;SET RD
BTFSS TEMP1,0x00 ;JUDGE PORTB.0,IF!=0,READ AGAIN,ELSE GO ON
GOTO PR11
BTFSS TEMP1,0x01 ;JUDGE PORTB.1,IF!=0,READ AGAIN,ELSE GO ON
GOTO PR11
BSF STATUS,RP0 ;SET TO BANK1
MOVLW 0x00 ;PORTB SET TO OUTPUT
MOVWF TRISB
BCF STATUS,RP0 ;SET BACK TO BANK0
MOVLW 0xFB ;CLR CD
ANDWF PORTA,F
MOVF DAT2,W ;WRITE DAT2 TO PORTB
MOVWF PORTB
MOVLW 0xFE ;CLR WR
ANDWF PORTA,F
MOVLW 0x01 ;SET WR
IORWF PORTA,F
PR12: ;无参数子程序入口
BSF STATUS,RP0 ;SET TO BANK1
MOVLW 0x00 ;PORTA SET TO OUTPUT
MOVWF TRISA
MOVLW 0xFF ;PORTB SET TO INPUT
MOVWF TRISB
BCF STATUS,RP0 ;SET BACK TO BANK0
MOVLW 0x04
IORWF PORTA,F ;SET CD
MOVLW 0xFD
ANDWF PORTA,F ;CLR RD
MOVF PORTB,W ;READ PORTB
MOVWF TEMP1
MOVLW 0x02
IORWF PORTA,F ;SET RD
BTFSS TEMP1,0x00 ;JUDGE PORTB.0,IF!=0,READ AGAIN,ELSE GO ON
GOTO PR12
BTFSS TEMP1,0x01 ;JUDGE PORTB.1,IF!=0,READ AGAIN,ELSE GO ON
GOTO PR12
BSF STATUS,RP0 ;SET TO BANK1
MOVLW 0x00 ;PORTB SET TO OUTPUT
MOVWF TRISB
BCF STATUS,RP0 ;SET BACK TO BANK0
MOVF COM,W ;WRITE COM TO PORTB
MOVWF PORTB
MOVLW 0xFE ;CLR WR
ANDWF PORTA,F
MOVLW 0x01 ;SET WR
IORWF PORTA,F
RETURN
;========字符写入程序============================================
WRT_C:
MOVF Y,W
MOVWF PARA1
MOVLW 0x1E
MOVWF PARA2
CALL MULT ;Y*30->PARA2(H),PARA
MOVF X,W
ADDWF PARA1,F ;PARA1+X->PARA1
BTFSS STATUS,C ;IF CARRIED, PARA2+1->PARA2
GOTO WRT_C1
MOVLW 0x01
ADDWF PARA2,F ;1+PARA2->PARA2
WRT_C1:
MOVF PARA1,W
MOVWF DAT1 ;X+PARA1->DAT1
MOVF PARA2,W ;PARA2->DAT2
MOVWF DAT2
MOVLW 0x24 ;0x24->COM
MOVWF COM
CALL PR1 ;CALL PR1
MOVF CODEA,W ;CODEA->DAT2
MOVWF DAT2
MOVLW 0xC4 ;0xC4->COM
MOVWF COM
CALL PR11 ;CALL PR11
MOVLW 0x0C
ADDWF PARA2,F ;PARA2->DAT2
MOVF PARA2,W
MOVWF DAT2
MOVLW 0x24 ;0x24->COM
MOVWF COM
CALL PR1 ;CALL PR1
MOVF ATTR,W ;ATTR->DAT2
MOVWF DAT2
MOVLW 0xC4 ;0xC4->COM
MOVWF COM
CALL PR11 ;CALL PR11
RETURN
;==========清屏子程序=========================================
CLEAR:
MOVLW 0x00
MOVWF DAT1
MOVLW 0x00
MOVWF DAT2
MOVLW 0x24
MOVWF COM
CALL PR1
MOVLW 0x20
MOVWF TEMP2
MOVLW 0x00
MOVWF TEMP3
CLEAR1:
MOVLW 0x00
MOVWF DAT2
MOVLW 0xC0
MOVWF COM
CALL PR11
DECFSZ TEMP3,F
GOTO CLEAR1
DECFSZ TEMP2,F
GOTO CLEAR1
RETURN
;=========建汉字库程序=========================================
CGRAM:
MOVLW 0x03
MOVWF DAT1
MOVLW 0x00
MOVWF DAT2
MOVLW 0x22
MOVWF COM
CALL PR1 ;建立CGRAM首地址
MOVLW 0x00
MOVWF DAT1
MOVLW 0x1C
MOVWF DAT2
MOVLW 0x24
MOVWF COM
CALL PR1 ;显示地址设置为1C00H
MOVF CNT,W
MOVWF PARA1
MOVLW 0x20 ;CNT*32=所建汉字库的字模数
MOVWF PARA2
CALL MULT
INCF PARA2,F
MOVLW 0x00
MOVWF COUNT1
CGRAM1:
CALL TABLE_1
MOVWF DAT2
MOVLW 0xC0
MOVWF COM
CALL PR11 ;一次读写数据
INCF COUNT1,F
DECFSZ PARA1,F
GOTO CGRAM1
DECFSZ PARA2,F
GOTO CGRAM1
RETURN
;========字符写入程序============================================
WRT_CT:
MOVF Y,W
MOVWF PARA1
MOVLW 0x1E
MOVWF PARA2
CALL MULT ;Y*30->PARA2(H),PARA1(L)
MOVF X,W
ADDWF PARA1,F ;PARA1+X->PARA1
BTFSS STATUS,C ;IF CARRIED, PARA2+1->PARA2
GOTO WRT_CT1
INCF PARA2,F ;1+PARA2->PARA2
WRT_CT1:
MOVF PARA1,W
MOVWF DAT1 ;X+PARA1->DAT1
MOVF PARA2,W ;PARA2->DAT2
MOVWF DAT2
MOVLW 0x24 ;0x24->COM
MOVWF COM
CALL PR1 ;CALL PR1
MOVF CT_CODE,W
MOVWF DAT2
MOVLW 0xC4
MOVWF COM
CALL PR11
MOVF PARA2,W
MOVWF TEMP4
MOVLW 0x0C
ADDWF TEMP4,F ;PARA2->DAT2
MOVF TEMP4,W
MOVWF DAT2
MOVLW 0x24 ;0x24->COM
MOVWF COM
CALL PR1 ;CALL PR1
MOVF ATTR,W ;ATTR->DAT2
MOVWF DAT2
MOVLW 0xC4 ;0xC4->COM
MOVWF COM
CALL PR11 ;CALL PR11
INCF PARA1,F
MOVF PARA1,W
MOVWF DAT1 ;X+PARA1->DAT1
MOVF PARA2,W ;PARA2->DAT2
MOVWF DAT2
MOVLW 0x24 ;0x24->COM
MOVWF COM
CALL PR1 ;CALL PR1
MOVLW 0x02
ADDWF CT_CODE,W
MOVWF DAT2
MOVLW 0xC4
MOVWF COM
CALL PR11
MOVF PARA2,W
MOVWF TEMP4
MOVLW 0x0C
ADDWF TEMP4,F ;PARA2->DAT2
MOVF TEMP4,W
MOVWF DAT2
MOVLW 0x24 ;0x24->COM
MOVWF COM
CALL PR1 ;CALL PR1
MOVF ATTR,W ;ATTR->DAT2
MOVWF DAT2
MOVLW 0xC4 ;0xC4->COM
MOVWF COM
CALL PR11 ;CALL PR11
DECF PARA1,F
MOVLW 0x1E
ADDWF PARA1,F
BTFSS STATUS,C
GOTO WRT_CT2
INCF PARA2,F
WRT_CT2:
MOVF PARA1,W
MOVWF DAT1
MOVF PARA2,W
MOVWF DAT2
MOVLW 0x24
MOVWF COM
CALL PR1
MOVLW 0x01
ADDWF CT_CODE,W
MOVWF DAT2
MOVLW 0xC4
MOVWF COM
CALL PR11
MOVF PARA2,W
MOVWF TEMP4
MOVLW 0x0C
ADDWF TEMP4,F ;PARA2->DAT2
MOVF TEMP4,W
MOVWF DAT2
MOVLW 0x24 ;0x24->COM
MOVWF COM
CALL PR1 ;CALL PR1
MOVF ATTR,W ;ATTR->DAT2
MOVWF DAT2
MOVLW 0xC4 ;0xC4->COM
MOVWF COM
CALL PR11 ;CALL PR11
INCF PARA1,F
MOVF PARA1,W
MOVWF DAT1 ;X+PARA1->DAT1
MOVF PARA2,W ;PARA2->DAT2
MOVWF DAT2
MOVLW 0x24 ;0x24->COM
MOVWF COM
CALL PR1 ;CALL PR1
MOVLW 0x03
ADDWF CT_CODE,W
MOVWF DAT2
MOVLW 0xC4
MOVWF COM
CALL PR11
MOVF PARA2,W
MOVWF TEMP4
MOVLW 0x0C
ADDWF TEMP4,F ;PARA2->DAT2
MOVF TEMP4,W
MOVWF DAT2
MOVLW 0x24 ;0x24->COM
MOVWF COM
CALL PR1 ;CALL PR1
MOVF ATTR,W ;ATTR->DAT2
MOVWF DAT2
MOVLW 0xC4 ;0xC4->COM
MOVWF COM
CALL PR11 ;CALL PR11
RETURN
;==============乘法子程序============================================
MULT:
MOVLW 0x00
MOVWF COUNT ;0->COUNT
MOVWF TEMP3 ;0->TEMP3
MOVWF RESULT_H ;0->RESULT_H
MOVWF RESULT_L ;0->RESULT_L
MULT_1:
BTFSS PARA1,0x00 ;TEST PARA1.0,IF PARA1.0=1,RESULT_L+PARA2->RESULT_L,
;RESULT_H+TEMP4->RESULT_H
GOTO MULT_3
MOVF PARA2,W ;RESULT_L+PARA2->RESULT_L
ADDWF RESULT_L,F
BTFSS STATUS,C ;IF RESULT_L+PARA2 CARRIED,RESULT_H+1->RESULT_H
GOTO MULT_2
INCF RESULT_H,F
MULT_2:
MOVF TEMP3,W
ADDWF RESULT_H,F ;RESULT_H+TEMP3->RESULT_H
MULT_3:
BCF STATUS,C ;CLEAR C
RLF TEMP3,F ;RLF H
BCF STATUS,C ;CLEAR C
RLF PARA2,F ;RLF L
BTFSS STATUS,C ;if L carried,H+1->H ,TEMP3+1->TENP1
GOTO NEXT
INCF TEMP3,F
NEXT:
BCF STATUS,C ;CLEAR C
RRF PARA1,F ; RRF PARA1
INCF COUNT,F ;COUNT+1->COUNT
MOVLW 0x08 ;JUDGE COUNT,IF COUNT!=8,CONTINUE
SUBWF COUNT,F
BTFSS STATUS,Z
GOTO MULT_1 ;CONTIUNE
MOVF RESULT_L,W
MOVWF PARA1 ;RESULT_L->PARA1
MOVF RESULT_H,W
MOVWF PARA2 ;RESULT_H->PARA2
RETURN
INT_SERVICE:
RETFIE
END