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]