; *********************************************************** ; * * ; * LCD Driver routines * ; * 213 bytes. Last Rev 16/11/96 * ; * * ; * Version 1 with port preservation for the port with * ; * the serial pins in it. * ; * * ; * The routines allow the user to completely control * ; * a hitachi or similar alphanumeric LCD display in * ; * 4-bit mode from a nominated port. MS nibble is * ; * the data and LSnibble is the control (3 bits) * ; * * ; * The constants mentioned in this program are ... * ; * * ; * En The 'E' bit of the display * ; * RW The R/W bit of the display * ; * RS The R/S bit of the display * ; * LCDDR The actual port DR register * ; * LCDDDR The actual port DDR register * ; * LCDOR The actual port OR register * ; * LCDDRC The copy of the DR register * ; * * ; *********************************************************** ; *********************** ; * Pause for 2.5mS * ; *********************** LCDPause ldi a, 0ffh ; wait for 25 counts 'x' times LCDPaus1 dec a jrnz LCDPaus1 dec x jrnz LCDPause ret ; ************************************* ; * Make LCD data port pins input * ; ************************************* LCDInput ld a, LCDDRC ; get the port copy andi a, 00fh ; strip off upper bits addi a, 0f0h ; set all data lines to '1' ld LCDDRC,a ; set port copy ldi LCDDDR, 00001111b ; modify the port lines to input ldi LCDOR, 00001111b ld LCDDR, a ; update the actual port ret ; ************************************** ; * Make LCD data port pins output * ; ************************************** LCDOutput ld a, LCDDRC ; get the port copy andi a, 00fh ; strip off the upper bits ld LCDDRC, a ; update the copy ld LCDDR, a ; set bus as output ldi LCDDDR, 11111111b ; set DDR ldi LCDOR, 11111111b ; and OR as output ret ; **************************** ; * Put LCDDRC to LCDDR * ; **************************** LCDOut ld a, LCDDRC ; get the port copy ld LCDDR, a ; update the port ret ; *************************************** ; * Set LCDDRC to MS nibble of 'a' * ; *************************************** LCDSetdata andi a, 0f0h ; preserve MS nibble ld LCDTmp, a ; temp storage ld a, LCDDRC ; get actual port value andi a, 00fh ; strip off MS nibble add a, LCDTmp ; put temp on port copy ld LCDDRC, a ; update the copy ret ; ****************************** ; * Wait while LCD is busy * ; ****************************** LCDBusy set RW, LCDDRC ; set control bit of LCD to read res RS, LCDDRC res En, LCDDRC call LCDInput ; make MS nibble input LCDBusy1 set En, LCDDRC ; set the 'E' bit on LS nibble call LCDOut jrr 7, LCDDR, LCDBusy2; busy? res En, LCDDRC ; reset the 'E' bit call LCDOut set En, LCDDRC ; set the 'E' bit again call LCDOut jp LCDBusy1 LCDBusy2 res En, LCDDRC ; reset 'E' bit call LCDOut set En, LCDDRC ; set 'E' bit call LCDOut res En, LCDDRC ; preset the 'E' bit ret ; ********************************* ; * Write Code to LCD display * ; ********************************* LCDCode ld w, a ; preserve 'a' call LCDBusy ; wait for LCD not busy res RS, LCDDRC ; set to register mode jp LCDWrite ; ************************************* ; * Write LCD Data to the display * ; ************************************* LCDData ld w, a ; preserve 'a' call LCDBusy ; wait for LCD not busy set RS, LCDDRC ; set to data mode LCDWrite res RW, LCDDRC ; set write call LCDOutput ; update port ld a, w ; get copy andi a, 11110000b ; strip off MS nibble call LCDSetdata ; put it on the bus set En, LCDDRC ; toggle 'E' call LCDOut res En, LCDDRC call LCDOut ld a, w ; get copy again sla a ; get the LS nibble sla a sla a sla a call LCDSetdata ; put it on the bus set En, LCDDRC ; toggle 'E' again call LCDOut res En, LCDDRC call LCDOut ret ; ********************************** ; * Initialise the LCD display * ; ********************************** LCDInit res RW, LCDDRC ; set write mode res RS, LCDDRC ; set register mode res En, LCDDRC ; reset 'E' call LCDOutput ldi a, 00110000b ; LCD to 8 bit mode call LCDSetdata ; put on bus ldi w, 003h ; do this 3 times LCDInit1 set En, LCDDRC ; toggle 'E' call LCDOut res En, LCDDRC call LCDOut ldi x, 00fh ; wait a while each time call LCDPause dec w jrnz LCDInit1 ldi a, 00100000b ; LCD to 4 bit mode call LCDSetdata ; put on bus set En, LCDDRC ; toggle 'E' call LCDOut res En, LCDDRC call LCDOut ldi x, 00fh ; wait a while again call LCDPause ldi a, 00101000b ; set cursor etc call LCDCode ; write code to LCD ldi x, 00fh ; pause call LCDPause ldi a, 00001101b ; LCD setup info call LCDCode ; write code to LCD ldi a, 00000001b ; LCD clear screen call LCDCode ; write code to LCD ldi x, 00fh ; pause call LCDPause ret