eva 发表于 2012-8-20 18:49:35

PIC16F877A与TS1620-1字符型液晶显示模块的试验程序

PIC16F877A与TS1620-1字符型液晶显示模块的试验程序这是本人刚学PIC时编的一段试验程序,用来驱动TS1620型字符液晶显示模块,传上来的程序是经本人实测后通过的,各位按图接线后,可以直接写入实验。此LCD模块在深圳赛格很易买到,带背光,价格16元(很划算吧?),对于初学PIC的朋友来说应该很合适。
如果各位认为不错请回贴表示支持,如果认为有什么不妥的地方请高手指正,谢谢!
上传的压缩包中有电路图、测试照片、TS1620型字符液晶显示模块的详细资料(注:SMA1602A与TS1620-1完全一样,厂家提供的TS1620-1资料是E文的,没要。)。
以下内容只有回复后才可以浏览
;********************************LCD模块测试程序**************************

;*********************************器件说明*********************************
;用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_RSEQU02H
LCD_RWEQU01H
LCD_EEQU00H
COUNT1EQU020H
COUNT2EQU021H
COUNT3EQU022H
COUNT4EQU023H
DATA_TEMP EQU041H
DATADOEQU042H
;*********************************************************
ORG 0000H      ;上电复位初始地址
GOTO MAIN
;*********************************************************
ORG 0010H      ;主程序起始地址
MAIN
;初始化端口   
BANKSELADCON1      ;选择体1
BCF   INTCON,GIE    ;关闭中断
MOVLW07H
MOVWFADCON1   ;上电时有A/D转换功能的端子全部被设为了A状态,
MOVLW0XFF
MOVWFTRISA   ;暂时将A口设为输入   
CLRFTRISB   ;设B口为输出
CLRFTRISC   ;设C口为输出
CLRFTRISE   ;设E口为普通I/O口,RE0-RE2为输出口
MOVLW0XFF
MOVWFTRISD   ;暂时将D口设为输入   
BANKSELPORTC   ;选择体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模块第一行字符显示子程序,显示"*LSLiengsing*"
   ;由于每向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
   BANKSELTRISB         ;选择体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
   BANKSELTRISB         ;选择体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控制线恢复成写状态.
   BANKSELTRISB         ;选择体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
   DECFSZCOUNT2
   GOTO    LOOP23
   DECFSZCOUNT3
   GOTO    LOOP22
   DECFSZCOUNT4
   GOTO    LOOP21
   RETURN
;***************************
DELAYTIME250
   MOVLW   D'10
   MOVWF   COUNT4
LOOP41
   MOVLW   D'255
   MOVWF   COUNT3
LOOP42
   MOVLW   D'255
   MOVWF   COUNT2
LOOP43
   DECFSZCOUNT2
   GOTO    LOOP43
   DECFSZCOUNT3
   GOTO    LOOP42
   DECFSZCOUNT4
   GOTO    LOOP41
   RETURN
   END
页: [1]
查看完整版本: PIC16F877A与TS1620-1字符型液晶显示模块的试验程序