英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流
标题: PIC16F877A与TS1620-1字符型液晶显示模块的试验程序 [打印本页]
作者: eva 时间: 2012-8-20 18:49
标题: 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_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
欢迎光临 英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流 (http://enroobbs.com/) |
Powered by Discuz! X3.2 |