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

📄 lcd test.asm

📁 TS-1620原理图和程序 TS-1620原理图和程序
💻 ASM
字号:
;********************************LCD模块测试程序**************************
;编程:刘钢
;日期:2005/1/21
;*********************************器件说明*********************************
;用PIC16F877A驱动LCD模块
;LCD模块,型号:ST1620-1
;LCD模块初始化,由厂家提供的资料显示,其初始化过程为:
;1----延时15ms
;2----写指令38H(写入之前不用检测Busy信号)
;3----延时5ms
;4----再次写入38H指令(写入之前不用检测Busy信号),至于为什么要重复写入现在不清楚,而且下面还要写一次.
;5----延时5ms
;4----再次写入38H指令(写入之前不用检测Busy信号)
;5----检测Busy信号;
;6----写指令38H,此条指令是将LCD显示模块设置为8位数据线,双行,5X7点阵显示
;7----检测Busy信号;
;8----写指令08H,关闭显示
;9----检测Busy信号;
;10---写指令01H,显示清屏
;以后写入光标等的控制指令.
;**********************************************************
LIST   P=PIC16F877A                     ;告诉汇编器所要汇编的器件型号
INCLUDE "P16F877.INC"                   ;汇编程序的头文件

;设置单片机的特殊存储器位,使用HS(高速)晶振,打开上电延时复位功能,
;关闭看门狗,关闭低电压编程功能.
__CONFIG     _HS_OSC &_PWRTE_ON&_WDT_OFF&_LVP_OFF
;注意:在CONFIG前面一定要加上两条下画线,否则汇编时会出错!!!
;************************************************************
	LCD_RS		EQU  02H
	LCD_RW		EQU  01H
	LCD_E		EQU  00H
	COUNT1		EQU  020H
	COUNT2		EQU  021H
	COUNT3		EQU  022H
	COUNT4		EQU  023H
	DATA_TEMP	EQU  041H
	DATADO		EQU  042H
;*********************************************************
ORG 0000H								;上电复位初始地址
	GOTO MAIN
;*********************************************************
ORG 0010H								;主程序起始地址
MAIN
;初始化端口    
	BANKSEL		ADCON1  				;选择体1
	BCF			INTCON,GIE				;关闭中断
	MOVLW		07H
	MOVWF		ADCON1					;上电时有A/D转换功能的端子全部被设为了A状态,
	MOVLW		0XFF
	MOVWF		TRISA					;暂时将A口设为输入     
	CLRF		TRISB					;设B口为输出 
	CLRF		TRISC					;设C口为输出  
	CLRF		TRISE					;设E口为普通I/O口,RE0-RE2为输出口 
	MOVLW		0XFF
	MOVWF		TRISD					;暂时将D口设为输入   
	BANKSEL		PORTC					;选择体0

;初始化LCD模块***********************************************************************
     CALL     DELAYTIME10              ;LCD上电延时15秒钟,使LCD上建立工作所需电压.
     CALL     DELAYTIME10
     MOVLW    038H                     ;写入38H指令,本来在此不用检测Busy信号(在COMAND_WR子程序
     CALL     COMAND_WR                 ;中包含有检测Busy信号的子程序),但此处不想单独编写命令写
                                       ;入程序,所以全部用同一个命令写入子程序.
     CALL     DELAYTIME5
     MOVLW    038H                     ;再次写入38H指令(写入之前不用检测Busy信号),至于为什么要
     CALL     COMAND_WR                 ;重复写入现在不清楚,而且下面还要写一次.
     CALL     DELAYTIME5
     MOVLW    038H
     CALL     COMAND_WR
     CALL     DELAYTIME5
     MOVLW    038H
     CALL     COMAND_WR
     MOVLW    08H                      ;并闭LCD模块的显示.
     CALL     COMAND_WR
     MOVLW    01H                      ;清LCD模块显示.
     CALL     COMAND_WR
     MOVLW    06H                      ;将模块设为向显示数据存贮器写入一个数据后,地址或光标加
     CALL     COMAND_WR                 ;1,即后写入的字符处于显示屏的右边.


;以下为LCD显示测试程序**************************************************************
;为了使程序具有通用性,所以将命令字的写入,数据的写入与读出程序都做成了子程序.
     MOVLW    0CH                   ;开LCD模块的显示
     CALL     COMAND_WR
LCD_DISPLAY
     MOVLW    080H                  ;设置第一行字符从第一位开始显示.由于已经将指针
     CALL     COMAND_WR              ;设为了每向显示存贮器写入一个数据指针加1,所以越
                                    ;后写入的数据会越靠近右边.另外,由于在LCD模块的
                                    ;初始化时已经写入了清显示命令,光标及显示存贮器
                                    ;的地址指针已回到了00H,所以在此处不写入此段命令
                                    ;也可以.
     
     CALL     LCD_DISPLAY1           ;显示第一行字符
     MOVLW    0C0H                  ;设置第二行字符从第一位开始显示.
     CALL     COMAND_WR
     CALL     LCD_DISPLAY2
DISPLAY_LOOP
     CALL     SWAP                  ;读出LCD显示数据存贮器中的字符数据并移位.
     CALL     DELAYTIME250          ;延时.
     MOVLW    0C0H                  ;写入显示数据存贮器的首地址.
     CALL     COMAND_WR
     MOVLW    030H                  ;数据表指针.
     MOVWF    FSR
WR_LOOP
     MOVF     INDF,W                ;将数据表中的数据写入到LCD模块显示数据存贮器中.
     CALL     DATA_WR
     INCF     FSR
     MOVF     FSR,W
     SUBLW    040H                  ;是否已经将16个字符数据全部写入到LCD模块中.
     BTFSS    STATUS,Z
     GOTO     WR_LOOP               ;没有写完则返回继续写入.
     GOTO     DISPLAY_LOOP    

;*****************************以下为各子程序********************************
;移位子程序
;程序功能:使字符向左流动并循环显示.在本程序中,只是第二行的字符会流动显示,第一行字符固定显示.
;移位原理:将LCD模块的显示存贮器内的40H~4FH(对应第二行显示存贮器的第1字符到第16字符)数据读出,
;         依次放置于地址为30H~3FH的数据寄存器器中,然后将其整体向下移一位.以达到字符流动显示的
;         效果,并将40H中的数据取出放入30H中,以达到循环的效果.
SWAP
     MOVLW    030H                  ;设置数据表(30H~40H寄存器)指针起始值
     MOVWF    FSR                   ;数据表指针.
     MOVLW    0C0H                  ;设置想要读出的LCD模块的显示存贮器的起始地址,此处的C0H对
                                    ;应LCD模块第二行的第1个字符
     CALL     COMAND_WR
READ     
     CALL     DATA_RD                ;调数据读出子程序从LCD模块的显示存贮器中读出数据,每读一次
                                    ;LCD显示存贮器的地址指针会自动加1,不用人工干预.
     MOVF     DATA_TEMP,W            ;将子程序读出的数据存于W中.
     MOVWF    INDF                  ;用间接寻址指令将读出的数据存入以FSR为指针的寄存器中.
     INCF     FSR                   ;将指针加1,指向下一个寄存器.
     MOVF     FSR,W                 ;检查指针数值是否达到40H,如果达到40H表明已经读出了16个数据
     SUBLW    040H                  ;将指针数据与40H相减.
     BTFSS    STATUS,Z              ;如果为零则状态寄存器的Z位置1.
     GOTO     READ                  ;如果不为零则表示还没有读出16个数据,转回再继续读出.
     MOVLW    03FH                  
     MOVWF    FSR                   ;设置寄存器指针,这次的指针用于移位.
RD_LOOP
     MOVF     INDF,W                ;将指针所指的寄存器中的数据取出.
     INCF     FSR                   ;将指针加1.
     MOVWF    INDF                  ;将先前从寄存器中取出的数据写入到下一个寄存器中(因为指针被加1).
     DECF     FSR                   ;将指针减1,消去刚才加上的1.
     DECF     FSR                   ;将指针减1,指向上一个寄存器.
     MOVF     FSR,W
     SUBLW    02FH                  ;判断移位16个数据
     BTFSS    STATUS,Z
     GOTO     RD_LOOP               ;如果移位没有完成则继续移位. 
     MOVF     040H,W                ;将40H中的数据(实际是移位前3FH中的数据)放入30H中,以达到循环的效果.
     MOVWF    030H
     RETURN

;显示子程序********************
LCD_DISPLAY1
   ;LCD模块第一行字符显示子程序,显示"*LS  Liengsing*"
   ;由于每向LCD模块的显示存贮器中写入一个字符模块的显示存贮器地址指针就加1,不用人工干预.
     MOVLW    '*'
     CALL     DATA_WR
     MOVLW    '*'
     CALL     DATA_WR
     MOVLW    'L'
     CALL     DATA_WR
     MOVLW    'S'
     CALL     DATA_WR
     MOVLW    ' '
     CALL     DATA_WR
     MOVLW    ' '
     CALL     DATA_WR
     MOVLW    'E'
     CALL     DATA_WR
     MOVLW    'n'
     CALL     DATA_WR
     MOVLW    'g'
     CALL     DATA_WR
     MOVLW    'i'
     CALL     DATA_WR
     MOVLW    'n'
     CALL     DATA_WR
     MOVLW    'e'
     CALL     DATA_WR
     MOVLW    'e'
     CALL     DATA_WR
     MOVLW    'r'
     CALL     DATA_WR
     MOVLW    '*'
     CALL     DATA_WR
     MOVLW    '*'
     CALL     DATA_WR
     RETURN

LCD_DISPLAY2
   ;LCD模块第二行字符显示子程序,显示"****Liu Gang****"
     MOVLW    '*'
     CALL     DATA_WR
     MOVLW    '*'
     CALL     DATA_WR
     MOVLW    '*'
     CALL     DATA_WR
     MOVLW    '*'
     CALL     DATA_WR
     MOVLW    'L'
     CALL     DATA_WR
     MOVLW    'i'
     CALL     DATA_WR
     MOVLW    'u'
     CALL     DATA_WR
     MOVLW    ' '
     CALL     DATA_WR
     MOVLW    'G'
     CALL     DATA_WR
     MOVLW    'a'
     CALL     DATA_WR
     MOVLW    'n'
     CALL     DATA_WR
     MOVLW    'g'
     CALL     DATA_WR
     MOVLW    '*'
     CALL     DATA_WR
     MOVLW    '*'
     CALL     DATA_WR
     MOVLW    '*'
     CALL     DATA_WR
     MOVLW    '*'
     CALL     DATA_WR
     RETURN

;命令字写入子程序**************
COMAND_WR
     BCF      PORTE,LCD_RS		;置命令字操作.
     BCF      PORTE,LCD_RW		;置写入操作
     MOVWF    PORTB				;将要写入的命令数据送B端口.
     BSF      PORTE,LCD_E		;向LCD模块写入命令字时模块的Enable端应出现正脉冲
     NOP                      ;厂家给出的数据手册中要求E信号脉冲最小宽度为150ns
                              ;在时钟频率为20MHz时,PIC16F877指令周期为200ns,虽然
                              ;可以满足要求,但为了保险起见,建议在中间插入一个NOP指令.
     BCF      PORTE,LCD_E
     CALL     BUSYCHECK       ;在每次写入完后检查LCD模块的Busy信号,此信号置1表示还不能进行下一次写入
     RETURN
;数据写入子程序**************
DATA_WR
     BSF      PORTE,LCD_RS        ;置数据操作.
     BCF      PORTE,LCD_RW        ;置写入操作
     MOVWF    PORTB           ;将要写入的数据送B端口.
     BSF      PORTE,LCD_E         ;进行写入操作
     NOP
     BCF      PORTE,LCD_E
     CALL     BUSYCHECK       ;在每次写入完后检查LCD模块的Busy信号,此信号置1表示还不能进行下一次写入
     RETURN
;读数据子程序***************
DATA_RD
     BANKSEL  TRISB           ;选择体1
     MOVLW    0FFH
     MOVWF    TRISB           ;将B口方向设为输入方式
     BCF      STATUS,RP0      ;回到体0
     BSF      PORTE,LCD_RS        ;置数据操作.
     BSF      PORTE,LCD_RW        ;置读出操作.
     BSF      PORTE,LCD_E         ;从LCD模块的显示存贮器中读出数据.
     NOP
     BCF      PORTE,LCD_E
     MOVF     PORTB,W         
     MOVWF    DATA_TEMP        ;将读出的数据保存.
     CALL     BUSYCHECK       ;在每次读出完后检查LCD模块的Busy信号,此信号置1表示还不能进行下一次写入     
     RETURN
     
;Busy信号检测子程序*********
BUSYCHECK
     BANKSEL  TRISB           ;选择体1
     MOVLW    0FFH
     MOVWF    TRISB           ;将B口方向设为输入方式
     BCF      STATUS,RP0      ;回到体0
     BCF      PORTE,LCD_RS        ;置命令字操作.
     BSF      PORTE,LCD_RW        ;置读出操作.
     BSF      PORTE,LCD_E
     NOP
     BCF      PORTE,LCD_E
     BTFSC    PORTB,7         ;检查LCD模块的Busy位是否为高.
     GOTO     BUSYCHECK       ;如果为高电平则等待.
     BCF      PORTE,LCD_RW        ;将RW控制线恢复成写状态.
     BANKSEL  TRISB           ;选择体1
     CLRF     TRISB           ;将B口恢复为输出状态.
     BCF      STATUS,RP0      ;返回到体0
     RETURN
; 以下为延时子程序 **************************************************  
 DELAYTIME5
     MOVLW    D'51
     MOVWF    COUNT2
LOOP01
     MOVLW    D'255
     MOVWF    COUNT3
LOOP02
     DECFSZ   COUNT3
     GOTO     LOOP02
     DECFSZ   COUNT2
     GOTO     LOOP01
     RETURN
;****************************
DELAYTIME10
     MOVLW    D'101
     MOVWF    COUNT2
LOOP11
     MOVLW    D'255
     MOVWF    COUNT3
LOOP12
     DECFSZ   COUNT3
     GOTO     LOOP12
     DECFSZ   COUNT2
     GOTO     LOOP11
     RETURN
;***************************
DELAYTIME500
     MOVLW   D'20
     MOVWF   COUNT4
LOOP21
     MOVLW   D'255
     MOVWF   COUNT3
LOOP22
     MOVLW   D'255
     MOVWF   COUNT2
LOOP23
     DECFSZ  COUNT2
     GOTO    LOOP23
     DECFSZ  COUNT3
     GOTO    LOOP22
     DECFSZ  COUNT4
     GOTO    LOOP21
     RETURN
;***************************
DELAYTIME250
     MOVLW   D'10
     MOVWF   COUNT4
LOOP41
     MOVLW   D'255
     MOVWF   COUNT3
LOOP42
     MOVLW   D'255
     MOVWF   COUNT2
LOOP43
     DECFSZ  COUNT2
     GOTO    LOOP43
     DECFSZ  COUNT3
     GOTO    LOOP42
     DECFSZ  COUNT4
     GOTO    LOOP41
     RETURN
     END

⌨️ 快捷键说明

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