;************************************************************************** ;* DISPAY DRIVER FOR 40*2 DISPLAYS * ;************************************************************************** ;************************************************************************** ;* (C)Display Code DAVID SCHOFIELD 2010 * ;* All rights reserved * ;************************************************************************** ;* Hardw. Rev: 1 Softw. Rev: 1.00 * ;* OSC.......: HS 20MHz Max. POWER.....: 5V DC * ;************************************************************************** ;############################################################################################################ ;# Hardware Configured As Follows # ;# 1x 40x2 display with control lines on PORTA, running in 4 BIT mode. LCD Data on PORTB 0 - 4. # ;# # ;############################################################################################################ org 0x0000 goto main LIST NOLIST ;========================================================================== ; ; Verify Processor ; ;========================================================================== IFNDEF __16F877A MESSG "Processor-header file mismatch. Verify selected processor." ENDIF ;========================================================================== ; ; Register Definitions ; ;========================================================================== W EQU H'0000' F EQU H'0001' ;----- Register Files------------------------------------------------------ PCL EQU H'0002' STATUS EQU H'0003' PORTA EQU H'0005' PORTB EQU H'0006' PORTC EQU H'0007' PORTD EQU H'0008' PORTE EQU H'0009' TRISA EQU H'0085' TRISB EQU H'0086' TRISC EQU H'0087' TRISD EQU H'0088' TRISE EQU H'0089' CMCON EQU H'009C' ADCON1 EQU H'009F' ;----- STATUS Bits -------------------------------------------------------- RP1 EQU H'0006' RP0 EQU H'0005' Z EQU H'0002' C EQU H'0000' ;-------Configuration Bits------------------- _CP_OFF EQU H'3FFF' _LVP_OFF EQU H'3F7F' _BODEN_ON EQU H'3FFF' _PWRTE_ON EQU H'3FF7' _WDT_OFF EQU H'3FFB' _HS_OSC EQU H'3FFE' LIST __CONFIG _BODEN_ON & _CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _HS_OSC ERRORLEVEL 0, -302 ;suppress bank selection messages ;----- CUSTOM Bits -------------------------------------------------------- LCD_CTRL Equ PORTA ;define PORTA as LCD control LCD_DATA Equ PORTB ;define PORTB as LCD data LCD_RS Equ 0x01 ;LCD handshake lines RS line on PORTA 1 LCD_E1 Equ 0x02 ;display enable 1 on PORTA 2 cblock 0x40 ;start of general purpose registers count ;used in looping routines count1 ;used in delay routine counta ;used in delay routine countb ;used in delay routine templcd ;temp store for 4 bit mode endc ; ############################################################ ; # End of Equates, setup ports and interupts # ; ############################################################ main BCF STATUS,RP0 ;DISSABLE A TO D and comparitors ON F877A BCF STATUS,RP1 CLRF PORTA BSF STATUS,RP0 MOVLW 0X06 MOVWF ADCON1 MOVLW 0XCF MOVWF TRISA movlw 0x07 movwf CMCON ;turn comparators off SetPorts bsf STATUS,RP0 ;select bank 1 movlw 0x00 movwf TRISA ;set PORTA as output movwf TRISB ;set PORTB as output bcf STATUS,RP0 ;select bank 0 ; ################################################## ; # MAIN PROGRAM START # ; ################################################## clrf count ;clear all ports so we start at a known point clrf LCD_CTRL clrf LCD_DATA call Delay100 ;wait for LCD to settle call LCD_Init ;setup LCD call LCD_Line1 call lcd_txt ;start off with display showing text from lcd_txt loop call LCD_Line2 ;display lcd_txt again on line 2 juist to test LCD call lcd_txt loop goto loop ; ##################################################################### ; # Main Program Ends. Subroutines and text tables start # ; ##################################################################### text addwf PCL, f retlw 'F' retlw 'o' retlw 'r' retlw 't' retlw 'y' retlw ' ' retlw 'X' retlw '2' retlw ' ' retlw 'd' retlw 'i' retlw 's' retlw 'p' retlw 'l' retlw 'a' retlw 'y' retlw ' ' retlw 'd' retlw 'r' retlw 'i' retlw 'v' retlw 'e' retlw 'r' retlw '.' retlw 'T' retlw 'e' retlw 's' retlw 't' retlw ' ' retlw 'b' retlw 'y' retlw ' ' retlw 'D' retlw 'a' retlw 'v' retlw 'e' retlw '.' retlw 'S' retlw '1' retlw '0' retlw 0x00 ; ######################################################################################################## ; # Title subroutines. These are used to display static info on line 1 of display 1 # ; ######################################################################################################## lcd_txt clrf count ;set counter register to zero txt_loop movf count, w ;put counter value in W call text ;get a character from the text table xorlw 0x00 ;is it a zero? btfsc STATUS, Z goto to_main call LCD_Char incf count, f goto txt_loop to_main retlw 0x00 ; ######################################################################################################## ; # Initialise the displays done twice to enable different setup on each display if needed # ; ######################################################################################################## LCD_Init movlw 0x20 ;initialise display call LCD_Cmd ;Set 4 bit mode movlw 0x28 ;Set display shift call LCD_Cmd movlw 0x06 ;Set display character mode call LCD_Cmd movlw 0x0c ;Set display on/off and cursor command call LCD_Cmd call LCD_Clr ;clear display call Delay5 retlw 0x00 ; ##################################### ; # command output routine # ; ##################################### LCD_Cmd movwf templcd swapf templcd, w ;send upper nibble andlw 0x0f ;clear upper 4 bits of W movwf LCD_DATA bcf LCD_CTRL, LCD_RS ;RS line to 0 call Pulse_e ;Pulse the E line high movf templcd, w ;send lower nibble andlw 0x0f ;clear upper 4 bits of W movwf LCD_DATA bcf LCD_CTRL, LCD_RS ;RS line to 0 call Pulse_e ;Pulse the E line high call Delay10 retlw 0x00 ; ##################################### ; # character output routine # ; ##################################### LCD_Char movwf templcd swapf templcd, w ;send upper nibble andlw 0x0f ;clear upper 4 bits of W movwf LCD_DATA bsf LCD_CTRL, LCD_RS ;RS line to 1 call Pulse_e ;Pulse the E line high movf templcd, w ;send lower nibble andlw 0x0f ;clear upper 4 bits of W movwf LCD_DATA bsf LCD_CTRL, LCD_RS ;RS line to 1 call Pulse_e ;Pulse the E line high call Delay5 retlw 0x00 ; ############################################################################# ; # LCD Cursor CTRL Routines. Not all used but left in for final setup # ; ############################################################################# LCD_Line1 movlw 0x80 ;move to 1st row, first column call LCD_Cmd retlw 0x00 LCD_Line2 movlw 0xc0 ;move to 2nd row, first column call LCD_Cmd retlw 0x00 LCD_Line1W addlw 0x80 ;move to 1st row, column W call LCD_Cmd retlw 0x00 LCD_Line2W addlw 0xc0 ;move to 2nd row, column W call LCD_Cmd retlw 0x00 LCD_CurOn movlw 0x0d ;Set display on/off and cursor command call LCD_Cmd retlw 0x00 LCD_CurOff movlw 0x0c ;Set display on/off and cursor command call LCD_Cmd retlw 0x00 LCD_Clr movlw 0x01 ;Clear display call LCD_Cmd retlw 0x00 decpoint movlw 0x2e ;Routine to add a decimal point call LCD_Char return ; ################################# ; # Delay routines. # ; ################################# Delay100 movlw d'100' ;delay 100mS goto d0 Delay80 movlw d'80' ;delay 80ms goto d0 Delay50 movlw d'50' ;delay 50mS goto d0 Delay20 movlw d'20' ;delay 20mS goto d0 Delay10 movlw d'10' ;delay 10mS goto d0 Delay5 movlw d'05' ;delay 5mS goto d0 Delay1 movlw 0x01 ;delay 1.000 ms (20 MHz clock) d0 movwf count1 d1 movlw 0xC7 ;delay 1mS movwf counta movlw 0x05 movwf countb Delay_0 decfsz counta, f goto $+2 decfsz countb, f goto Delay_0 decfsz count1 ,f goto d1 retlw 0x00 ; ############################################################# ; # Pulse routines for the E line of displays 1 & 2 # ; ############################################################# Pulse_e bsf LCD_CTRL, LCD_E1 ;toggle the E line of display 1 nop bcf LCD_CTRL, LCD_E1 retlw 0x00 end