; File: LCDP@.A51 Date: 12/15/92 ; ; /* (c) Copyright BLUE EARTH RESEARCH, MANKATO, MN 1992. */ ; /* All rights reserved. */ ; $ TITLE (4-BIT BASIC LCD INTERFACE TO PORT1) $ DEBUG XREF ERRORPRINT NOGEN $ DATE (12-15-92) $ PW(96) PL(60) ; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ; º º ; º LCD MODULE SOFTWARE DRIVER ROUTINE º ; º º ; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ; ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ ; ³ Written By: Thomas Bachmann ³ ; ³ Blue Earth Research, Mankato, MN 56001 ³ ; ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; ; This program implements a 4-bit interface to a LCD module ; using a total of 6 I/O lines on Port1. Four lines are used ; for data, with two additional controls lines for "Register ; Select" and "E". The Register Select line is used to specify ; whether data is currently being written to the Command or ; Data register. The E signal is used to clock the data to the ; LCD module. A third control line, R/W, is not used in this ; application. Since data will only be written to the LCD, ; the R/W line is tied low (grounded). ; When this program is initialized from within BASIC by ; executing the "CALL 7F00H" Statement, characters are written ; to the LCD by the "PRINT@" Statement. A Carriage Return ; (0DH) will cause the cursor to be at the "home" position, ; and a Line Feed (0AH) will place the cursor at the beginning ; of the second line. A Form Feed (0CH) will clear the screen ; and return the cursor to the home position. ; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ $ EJECT ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ DEFINITIONS SPECIFIC TO THE SYSTEM WIRING ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; THE FOLLOWING DEFINITIONS ASSUME THAT THE SYSTEM WIRING IS ; CONFIGURED WITH ALL CONNECTIONS TO PORT 1 AS FOLLOWS: ; SIGNAL CONTROLLER SIGNAL ; -------- ------------ -------- ; 22 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; DB4ÄÄÄÄÄÄÄÄÄÄÄ´ P1.0 ³ ; 9 ³ ³ ; DB5ÄÄÄÄÄÄÄÄÄÄÄ´ P1.1 ³ ; 21 ³ ³ +5V ÄÄÄÄÄVcc ; DB6ÄÄÄÄÄÄÄÄÄÄÄ´ P1.2 ³ ; 8 ³ ³ 1 ; DB7ÄÄÄÄÄÄÄÄÄÄÄ´ P1.3 GND ÃÄÄÄÄÄÄÄÄÄÄÄVee ; 20 ³ ³ 1 ; RSÄÄÄÄÄÄÄÄÄÄÄ´ P1.4 GND ÃÄÄÄÄÄÄÄÄÄÄÄVss ; 7 ³ ³ 1 ; E ÄÄÄÄÄÄÄÄÄÄÄ´ P1.5 GND ÃÄÄÄÄÄÄÄÄÄÄÄR/W ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; The LCD control lines are wired to the controller as follows: RS BIT P1.4 Eclk BIT P1.5 ; Note: The port pins are assigned in order to allow the ; use of the Micro-440's 2nd serial port ; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ; The following BASIC program can be used to demonstrate the ; functions of the LCD with this program: ; 10 CALL 7F00H : REM INITIALIZE LCD MODULE ; 20 PRINT@ "BLUE EARTH" : PRINT@ "RESEARCH" ; 30 DO : G=GET : UNTIL G : PRINT@ CHR$(12), ; 40 PRINT@ "LCD" : PRINT@ "DEMO" $ EJECT ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ DATA MEMORY DECLARATIONS ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; SEVERAL INTERNAL DATA MEMORY LOCATIONS ARE USED TO STORE ; COUNTERS, POINTERS, ETC. AS FOLLOWS: DSEG AT 18H COUNT1: DS 1 ; Temp timer registers COUNT0: DS 1 REG_SEL: DS 1 ; SELECT COMMAND OR DATA REG. TEMP_HOLD: DS 1 ; LCD BYTE, BUFFER POINTER ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SPACE EQU 20H CR EQU 0DH LF EQU 0AH FF EQU 0CH INITIALIZE EQU 7F00H ; PROGRAM BEGINNING CLEAR_DISPLAY EQU 0000$0001B ; "CLEAR DISPLAY" BYTE LINE2 EQU 1100$0000B ; "GOTO LINE 2" BYTE LINE1 EQU 1000$0000B ; "GOTO LINE 1" BYTE EXEC_TIME EQU 20 ; EXECUTION TIME ; FOR INSTRUCTIONS RESET EQU 1100$0011B ; "RESET" BYTE F_FIRST EQU 1100$0010B ; "FUNCTION SET" BYTES F_SET EQU 0010$1000B ; "FUNCTION SET" BYTES DOFF EQU 0000$1000B ; "DISPLAY OFF" BYTES DON EQU 0000$1100B ; "DISPLAY ON" BYTES ; NOTE: 0000$11cbB For "Display On," where ; c=1 for Cursor on, and b=1 for blinking character MODE EQU 0000$0110B ; "ENTRY MODE" BYTES SHIFTR EQU 0001$1100B ; "SHIFT RIGHT" BYTES SHIFTL EQU 0001$1000B ; "SHIFT LEFT" BYTES $ EJECT ; ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ ; ³ BEGINNING OF INITIALIZATION ROUTINE ³ ; ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; CSEG AT INITIALIZE ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ INITIALIZE USER LCD OUTPUT ALGORITHM ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; The following code places the jump vector in memory and ; sets the protection bit that tells BASIC where it should ; direct the PRINT@ output to. Start: MOV DPTR,#403CH ; POINT TO JUMP LOCATION MOV A,#2 ; LOAD LJMP MOVX @DPTR,A INC DPTR MOV A,#HIGH CHAR_OUTPUT MOVX @DPTR,A INC DPTR MOV A,#LOW CHAR_OUTPUT MOVX @DPTR,A SETB 39 ; PROTECTION BIT ; ------------------- INITIALIZE LCD MODULE ------------------- CLR Eclk MOV REG_SEL,#0C0H ; OUTPUT TO COMMAND REGISTER MOV COUNT1,#07FH ; WAIT FOR A LONG TIME ACALL WAIT_Z MOV P1,#RESET ; WRITE BYTE SETB Eclk ; CLOCK IT IN CLR Eclk MOV COUNT1,#9 ; WAIT AT LEAST 4.1 mS ACALL WAIT_Z MOV P1,#RESET ; WRITE BYTE ACALL CLOCK_N_WAIT MOV P1,#RESET ; WRITE BYTE ACALL CLOCK_N_WAIT MOV P1,#F_FIRST ; WRITE BYTE ACALL CLOCK_N_WAIT ; CLOCK IT IN MOV A,#F_SET ACALL OUTPUT ; FUNCTION SET MOV A,#DOFF ACALL OUTPUT ; TURN DISPLAY OFF ACALL Clear ; CLEAR DISPLAY MOV A,#MODE ACALL OUTPUT ; SET ENTRY MODE MOV A,#DON AJMP OUTPUT ; TURN DISPLAY ON ; AND RETURN TO BASIC ; ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ ; ³ CLEAR DISPLAY ³ ; ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; Clear: MOV REG_SEL,#0C0H ; OUTPUT TO COMMAND REGISTER Clear1: MOV A,#CLEAR_DISPLAY ACALL OUTPUT MOV COUNT1,#4 ; WAIT AT LEAST 2 mS WAIT_Z: MOV COUNT0,#0FFH DJNZ COUNT0,$ DJNZ COUNT1,WAIT_Z RET $ EJECT ; ---------------------- LCD UPDATE --------------------------- ; The following code is executed every time that the BASIC ; program executes a "PRINT@" Statement. After the statement ; is executed from within BASIC, the character to be output is ; in the accumulator. CHAR_OUTPUT: MOV REG_SEL,#0D0H ; POINT TO DATA REGISTER CJNE A,#SPACE,$+3 ; CHECK FOR A PRINTABLE CHAR JNC OUTPUT MOV REG_SEL,#0C0H ; POINT TO COMMAND REGISTER ; If the character is a Form Feed, the display is cleared and ; the cursor is placed at the beginning of the first line. CJNE A,#FF,CR_Chk ; Form Feed? SJMP Clear1 ; If the character is a carriage return, the display cursor is ; placed at the beginning of the first line of the display. CR_Chk: CJNE A,#CR,LF_Chk ; Carriage return? MOV A,#LINE1 SJMP OUTPUT ; If the character is a line feed, the display cursor is ; placed at the beginning of the second line of the display. LF_Chk: CJNE A,#LF,NoChar ; Line Feed? MOV A,#LINE2 ; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ $ EJECT ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ SUBROUTINE FOR SENDING A CHARACTER ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; SEND AN 8-BIT CHARACTER (OR COMMAND) TO THE LCD. OUTPUT: MOV TEMP_HOLD,A ; SAVE IT ; ------------------ OUTPUT CHARACTER HALF -------------------- SWAP A ANL A,#0FH ; GET RID OF LOWER HALF ORL A,REG_SEL ; SELECT COMMAND OR DATA MOV P1,A SETB Eclk CLR Eclk MOV A,TEMP_HOLD ; GET LOWER HALF AGAIN ; ------------------- OUTPUT SECOND HALF ---------------------- ANL A,#0FH ; OUTPUT OTHER CHAR HALF ORL A,REG_SEL ; SELECT COMMAND OR DATA MOV P1,A CLOCK_N_WAIT: SETB Eclk ; CLOCK IN THE BYTE CLR Eclk MOV COUNT0,#EXEC_TIME ; WAIT AT LEAST 120 uS DJNZ COUNT0,$ NoChar: RET ; Back to BASIC END ; Following is the HEX file derived from the assembled source ; file. This can be used for directly loading the program via ; MONITOR-51 and almost any terminal program. :107F000090403C7402F0A3747FF0A3745BF0D2271E :107F1000C295751AC075187FF1517590C3D295C27C :107F200095751809F1517590C3F18C7590C3F18C5A :107F30007590C2F18C7428F1777408F177F1477469 :107F400006F177740CE177751AC07401F177751832 :107F5000047519FFD519FDD518F722751AD0B4206C :107F6000005014751AC0B40C0280DFB40D04748084 :107F70008005B40A2174C0F51BC4540F451AF5904E :107F8000D295C295E51B540F451AF590D295C2952E :077F9000751914D519FD223B :00000001FF