; ; LCD module commands and utilities ; ;********************************************************************* DisLCD ; disable lcd module output ;********************************************************************* ; install this command in the CmdMenu lookup table CmdPC = $ ; save current inline assembly PC value org CurCmdMenuAdr ; set assembly PC to addr for new entry ; CmdMenu table entry data "LCDOFF\r", CmdPC, "Disable LCD output\r\n" CurCmdMenuAdr = $ ; set current CmdMenu addr for next entry org CmdPC ; begin cmd code gen at inline address bcf lcdFlags, LCDPrsnt ; clear lcd present flag goto DspLCD ; go display lcd status ; ;********************************************************************* EnLCD ; enable lcd module output ;********************************************************************* ; install this command in the CmdMenu lookup table CmdPC = $ ; save current inline assembly PC value org CurCmdMenuAdr ; set assembly PC to addr for new entry ; CmdMenu table entry data "LCDON\r", CmdPC, "Enable LCD output\r\n" CurCmdMenuAdr = $ ; set current CmdMenu addr for next entry org CmdPC ; begin cmd code gen at inline address call INIT_LCD ; initialize lcd module bsf lcdFlags, LCDPrsnt ; set lcd present flag ; fall through to display lcd status ; ;********************************************************************* DspLCD ; display lcd module status ;********************************************************************* ; install this command in the CmdMenu lookup table CmdPC = $ ; save current inline assembly PC value org CurCmdMenuAdr ; set assembly PC to addr for new entry ; CmdMenu table entry data "LCD\r", CmdPC, "Display LCD status\r\n" CurCmdMenuAdr = $ ; set current CmdMenu addr for next entry org CmdPC ; begin cmd code gen at inline address ; copy first part of output string into output buffer using FSR0 CpyTbl2Out LcdD btfsc lcdFlags, LCDPrsnt ; if lcd isn't present then skip goto LCDcont ; otherwise don't print NOT CpyTbl2Out NotD ; print NOT LCDcont CpyTbl2Out ActiveD ; complete output string return ; return from Cmd ; This is the end of the functions executable code ; ; These data statements store constant ascii output strings in program ; memory. They're accessed using the CpyTbl2Buf and CpyTblCont macros ; with the addresses given by the labels. LcdD ; constant string for lcd status display data "\nLCD module is ",0 NotD ; constant string for NOT display data "NOT ",0 ActiveD ; constant string for active display data "active\n",0 ; ; additional LCD routines ; InitLCD clrf lcdFlags ; initalize lcd flags return ; Cmd2LCD ; send cmd line to LCD btfss lcdFlags, LCDPrsnt ; skip if lcd present flag is set return ; otherwise return movlw 0x0D ; load CR char call SEND_CHAR ; send it to LCD movlw 0x0A ; load LF char call SEND_CHAR ; send it to LCD movlw '>' ; load prompt char call SEND_CHAR ; send it to LCD movfp rxPtr, FSR0 LineLCD incf FSR0 movfp INDF0, WREG call SEND_CHAR movlw 0x0D cpfseq INDF0 goto LineLCD return ; Out2LCD ; send output line to LCD btfss lcdFlags, LCDPrsnt ; skip if lcd present flag is set return ; otherwise return movfp txPtr, FSR0 OutLCD tstfsz INDF0 goto $+2 return movfp INDF0, WREG call SEND_CHAR incf FSR0 goto OutLCD ; ; LM032L lcd module initialization and interface routines and variables ; writteb in 17Cxx assembly. ; ; include this file after the cblock and org statement in the main file ; ; The interface is defined as 4 bit using D0-D3 of the port LCD defined ; below. The control signals are on the upper nibble of the same port. ; ; set the port used for the LCD interface here LCD EQU PORTC ; on the '756 demo board the LCD i/f is LCD_DDR EQU DDRC ; on PORTC LCD_BNK EQU 1 ; which is in bank 1 ; ; LCD Control Signal names. ; E EQU 6 ; LCD Enable control line RW EQU 5 ; LCD Read/Write control line RS EQU 4 ; LCD Register Select control line ; ; set the dewice frequency here Dev_Freq EQU D'16000000' ; Device Frequency is 4 MHz LCD_INIT_DELAY EQU (HIGH ((( Dev_Freq / 4 ) * D'46' / D'10000' ) / 3 ) ) + 1 ; ; LCD Module commands ; DISP_ON EQU 0x00C ; Display on DISP_ON_C EQU 0x00E ; Display on, Cursor on DISP_ON_B EQU 0x00F ; Display on, Cursor on, Blink cursor DISP_OFF EQU 0x008 ; Display off CLR_DISP EQU 0x001 ; Clear the Display ENTRY_INC EQU 0x006 ; ENTRY_INC_S EQU 0x007 ; ENTRY_DEC EQU 0x004 ; ENTRY_DEC_S EQU 0x005 ; DD_RAM_ADDR EQU 0x080 ; Least Significant 7-bit are for address DD_RAM_UL EQU 0x080 ; Upper Left coner of the Display CURS_LEFT EQU 0x10 ; shift cursor left CURS_RIGHT EQU 0x14 ; shift cursor right ; cblock ; variable declaration lcdFlags ; status flags for LCD module temp ; used by SEND_CHAR and SEND_CMD busyread ; used by BUSY_CHECK TEMP0 ; used for delay in INIT_LCD TEMP1 ; " " endc ; high active flags in lcdFlags LCDPrsnt equ 0 ; lcd module is present ; ; ;******************************************************************* ;* The LCD Module Subroutines * ;******************************************************************* ; ;******************************************************************* ;* SEND_CHAR - Sends character in W to LCD * ;* This routine splits the character into the upper and lower * ;* nibbles and sends them to the LCD, upper nibble first. * ;* The data is transmitted on the PORT<3:0> pins * ;* Affects: W and temp * ;******************************************************************* ; SEND_CHAR movlb LCD_BNK ; select SFR bank for LCD movwf temp ; save char to be sent call BUSY_CHECK ; wait for LCD ready ; movfp busyread, WREG ; DEBUG fetch last cursor position ; movwf PORTD ; DEBUG display on leds movlw 0x08 ; test for backspace cpfseq temp goto NOT_BACK ; if not keep going ; process backspace with wrap araound movfp busyread, WREG ; fetch cursor position bcf WREG, 6 ; clear row indicating bit tstfsz WREG ; skip if 0 to process wrap goto NOWRAP ; otherwise no wrap around movfp busyread, WREG ; fetch cursor position btg WREG, 6 ; toggle row iorlw D'19' ; set to last visible location bsf WREG, 7 ; set bit to create load addr cmd call SEND_CMD ; send to display movlw ' ' ; load space char to clear spot call SEND_CHAR ; recursively call to send movfp busyread, WREG ; fetch cursor position andlw 0x40 ; clear all but row indicating bit iorlw D'19' ; set to last visible location bsf WREG, 7 ; set bit to create load addr cmd call SEND_CMD ; send to display return NOWRAP movlw CURS_LEFT ; load command to backup cursor call SEND_CMD ; send the determined cmd to the display movlw ' ' ; load space char to clear spot call SEND_CHAR ; recursively call to send movlw CURS_LEFT ; backup cursor again call SEND_CMD ; send to display return NOT_BACK movlw 0x0D ; test for carriage return cpfseq temp goto NOT_CR ; if not keep going ; process carriage return movfp busyread, WREG ; fetch current cursor position andlw 0x40 ; clear all but row indicating bit bsf WREG, 7 ; set bit to create load addr cmd call SEND_CMD return NOT_CR movlw 0x0A ; test for line feed cpfseq temp goto NOT_LF ; if not keep going ; process line feed and clear rest of line movfp busyread, WREG ; fetch current cursor position btg WREG, 6 ; toggle row movwf TEMP0 ; save it bsf WREG, 7 ; set bit to create load addr cmd call SEND_CMD ; toggle to other row on lcd movfp busyread, WREG ; fetch curson position bcf WREG, 6 ; clear row indicating bit movwf TEMP1 ; save it SPACES ; clear rest of new row movlw 18 ; test for 19 or greater cpfsgt TEMP1 ; if cursor is in view skip goto BACK_UP ; otherwise backup to original position movlw ' ' ; load a space call SEND_CHAR ; recursively call to send incf TEMP1 ; inc cursor position goto SPACES BACK_UP ; go back to original position movfp TEMP0, WREG ; fetch old position bsf WREG, 7 ; set bit to create load addr cmd call SEND_CMD return NOT_LF ; printable character swapf temp, W ; get upper nibble into lower andlw 0x0F ; mask out D4-D7, clear RW movwf LCD ; output upper data nibble bsf LCD, RS ; set RS to data nop ; allow RS -> E > 140nS @ 33MHz bsf LCD, E ; raise E nop ; nop ; nop ; bcf LCD, E ; lower E > 450nS @ 33MHz movfp temp, WREG ; get lower nibble andlw 0x0F ; mask out D4-D7, clear RW movwf LCD ; output lower data nibble bsf LCD, RS ; set RS to data nop ; allow RS -> E > 140nS @ 33MHz bsf LCD, E ; raise E nop ; nop ; nop ; bcf LCD, E ; lower E > 450nS @ 33MHz ; test for wrap around movfp busyread, WREG ; fetch last cursor position bcf WREG, 6 ; clear row indicating bit sublw D'18' ; test for 19 or greater btfsc ALUSTA, C ; if cursor is out of view skip return ; otherwise return ; process carriage return and line feed movfp busyread, WREG ; fetch current cursor position andlw 0x40 ; clear all but row indicating bit btg WREG, 6 ; toggle row bsf WREG, 7 ; set bit to create load addr cmd call SEND_CMD return ; ;******************************************************************* ;* SendCmd - Sends command in W to LCD * ;* This routine splits the command into the upper and lower * ;* nibbles and sends them to the LCD, upper nibble first. * ;* The data is transmitted on the PORT<3:0> pins * ;* Affects: W and temp * ;******************************************************************* ; SEND_CMD movwf temp ; save cmd to be sent movlb LCD_BNK ; select SFR bank for LCD call BUSY_CHECK ; wait for LCD ready swapf temp, W ; get upper nibble into lower andlw 0x0F ; mask out D4-D7, clear RW and RS movwf LCD ; output upper data nibble nop ; allow RS & RW -> E > 140nS @ 33MHz bsf LCD, E ; raise E nop ; nop ; nop ; bcf LCD, E ; lower E > 450nS @ 33MHz movfp temp, WREG ; get lower nibble andlw 0x0F ; mask out D4-D7, clear RW and RS movwf LCD ; output lower data nibble nop ; allow RS & RW -> E > 140nS @ 33MHz bsf LCD, E ; raise E nop ; nop ; nop ; bcf LCD, E ; lower E > 450nS @ 33MHz return ; ;******************************************************************* ;* This routine checks the busy flag, returns when not busy * ;* If a the routine checks for ;* Affects: W and read value returned in busyread * ;******************************************************************* ; BUSY_CHECK call SHORT_DELAY ; delay some movlw 0x0F ; set data pins to input iorwf LCD_DDR ; bcf LCD, RS ; clear for cmd mode bsf LCD, RW ; set for read nop ; allow RW -> E > 140nS @ 33MHz bsf LCD, E ; raise E nop ; allow data access > 320nS nop ; even at 33MHz swapf LCD, W ; read upper nibble into W bcf LCD, E ; lower E > 450nS @ 33MHz andlw 0xF0 ; set lower nibble to 0 movwf busyread ; save in busyread nop ; allow > 1uS E cycle @ 33MHz bsf LCD, E ; raise E nop ; allow data access > 320nS nop ; even at 33MHz movfp LCD, WREG ; read lower nibble bcf LCD, E ; lower E > 450nS @ 33MHz andlw 0x0F ; set upper nibble to 0 iorwf busyread, W ; merge nibbles btfsc WREG, 7 ; if busy don't skip goto BUSY_CHECK ; check again movwf busyread ; otherwise save read value in busyread movlw 0xF0 ; set LCD port pins to output andwf LCD_DDR ; return ; return with lcd present ; ; This routine takes the calculated times that the delay loop needs to ; be executed, based on the LCD_INIT_DELAY EQUate that includes the ; frequency of operation. ; LCD_DELAY MOVLW LCD_INIT_DELAY ; MOVWF TEMP0 ; CLRF TEMP1 ; LOOP2 DECFSZ TEMP1, F ; Delay time = MSD * ((3 * 256) + 3) * Tcy GOTO LOOP2 ; = 4.6mS - jea DECFSZ TEMP0, F ; GOTO LOOP2 ; return SHORT_DELAY clrf WREG ; init WREG decfsz WREG ; delay 3 * 256 * Tcy goto $-1 ; return ; ; Initilize the LCD Display Module after power up ; INIT_LCD ; ; Initialize port LCD to drive lcd module ; movlb LCD_BNK ; select SFR bank for LCD bcf LCD_DDR, E ; set E as an output bcf LCD_DDR, RW ; set RW as an output bcf LCD_DDR, RS ; set RS as an output movlw 0xF0 ; andwf LCD_DDR ; set low nibble as data output clrf LCD ; init all bits in LCD to 0 ; delay > 15ms call LCD_DELAY call LCD_DELAY call LCD_DELAY call LCD_DELAY movlw 0x03 ; Command for 8-bit interface movwf LCD ; clearing RS & RW nop ; allow RS & RW -> E > 140nS @ 33MHz bsf LCD, E ; raise E nop ; nop ; nop ; bcf LCD, E ; lower E > 450nS @ 33MHz ; delay > 4.1ms call LCD_DELAY movlw 0x03 ; Command for 8-bit interface movwf LCD ; clearing RS & RW nop ; allow RS & RW -> E > 140nS @ 33MHz bsf LCD, E ; raise E nop ; nop ; nop ; bcf LCD, E ; lower E > 450nS @ 33MHz ; delay > 100us call LCD_DELAY movlw 0x03 ; Command for 8-bit interface movwf LCD ; clearing RS & RW nop ; allow RS & RW -> E > 140nS @ 33MHz bsf LCD, E ; raise E nop ; nop ; nop ; bcf LCD, E ; lower E > 450nS @ 33MHz ; delay > 100us call LCD_DELAY movlw 0x02 ; Command for 4-bit interface movwf LCD ; clearing RS & RW nop ; allow RS & RW -> E > 140nS @ 33MHz bsf LCD, E ; raise E nop ; nop ; nop ; bcf LCD, E ; lower E > 450nS @ 33MHz ; ; Command sequence for 4-bit mode and 2 lines of 5x8 characters ; movlw 0x02 ; 4-bit mode movwf LCD ; output upper cmd nibble nop bsf LCD, E ; raise E nop ; nop ; nop ; bcf LCD, E ; lower E > 450nS @ 33MHz movlw 0x08 ; 2 line display movwf LCD ; output lower cmd nibble nop ; allow > 1uS E cycle @ 33MHz bsf LCD, E ; raise E nop ; nop ; nop ; bcf LCD, E ; lower E > 450nS @ 33MHz ; ; Busy Flag should be valid after this point ; MOVLW DISP_OFF ; Display Off CALL SEND_CMD ; Send This command to the Display Module MOVLW CLR_DISP ; Clear the Display CALL SEND_CMD ; Send This command to the Display Module MOVLW ENTRY_INC ; Set Entry Mode Inc., No shift CALL SEND_CMD ; Send This command to the Display Module MOVLW DISP_ON ; Display On, no Cursor CALL SEND_CMD ; Send This command to the Display Module movlw 0x0A ; load LF char call SEND_CHAR ; send it to LCD RETURN
file: /Techref/piclist/andrewspicos/lcd.htm, NaNKB (1 imgs) in 0.257s is NaNKBps, updated: 2002/11/1 19:07, local time: 2025/4/5 19:15,
3.19.213.242:LOG IN
|
©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://massmind.org/techref/piclist/andrewspicos/lcd.htm"> piclist andrewspicos lcd</A> |
Did you find what you needed? |
Welcome to massmind.org! |
Welcome to massmind.org! |
.