; File: LCD_P13@.A51 Date: 5/20/93 ; ; /* (c) Copyright BLUE EARTH RESEARCH, MANKATO, MN 1993. */ ; /* All rights reserved. */ ; $ TITLE (4-BIT LCD PRINT@ DRIVER USING P1 & P3) $ DEBUG XREF ERRORPRINT $ NOGEN $ DATE (05-20-93) $ 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 P1 & P3. Four lines are used ; for data, with two additional Port3 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 should be 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 PORT1 & PORT3 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 ; 17 ³ ³ 1 ; RSÄÄÄÄÄÄÄÄÄÄÄ´ P3.4 GND ÃÄÄÄÄÄÄÄÄÄÄÄVss ; 4 ³ ³ 1 ; E ÄÄÄÄÄÄÄÄÄÄÄ´ P3.5 GND ÃÄÄÄÄÄÄÄÄÄÄÄR/W ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; The LCD control lines are wired to the controller as follows: RS BIT P3.4 Eclk BIT P3.5 ; Note that both of these signals can be reassigned to any ; of the available Port 3 signals (P3.2, P3.3, P3.4, P3.5) ; simply by changing the above definitions. ; Note: The port pins are assigned in order to allow the ; use of 4 of the Micro-440's PCA Modules ; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ; 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 Clock: DS 2 ; Timer Registers TEMP_HOLD: DS 1 ; LCD BYTE TEMP HOLDER ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 1111$0011B ; "RESET" BYTE F_FIRST EQU 1111$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 CLR RS ; OUTPUT TO COMMAND REGISTER MOV Clock+1,#0FFH ; WAIT FOR A LONG TIME ACALL WAIT_Z MOV P1,#RESET ; WRITE BYTE SETB Eclk ; CLOCK IT IN CLR Eclk MOV Clock+1,#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 ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ DISPLAY WRITING SUBROUTINES ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ ; ³ CLEAR DISPLAY ³ ; ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; CLEAR: CLR RS Clear1: MOV A,#CLEAR_DISPLAY ACALL OUTPUT MOV Clock+1,#10 ; WAIT AT LEAST 4.9 mS WAIT_Z: MOV Clock,#0FFH DJNZ Clock,$ DJNZ Clock+1,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: SETB RS ; POINT TO DATA REGISTER CJNE A,#SPACE,$+3 ; CHECK FOR A PRINTABLE CHAR JNC OUTPUT CLR RS ; 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 ORL A,#0F0H ; OUTPUT 1's ON UPPER HALF MOV P1,A SETB Eclk CLR Eclk MOV A,TEMP_HOLD ; GET LOWER HALF ORL A,#0F0H ; OUTPUT OTHER CHAR HALF MOV P1,A CLOCK_N_WAIT: SETB Eclk ; CLOCK IN THE BYTE CLR Eclk MOV Clock,#EXEC_TIME ; WAIT AT LEAST 120 uS DJNZ Clock,$ NoChar: RET ; Back to BASIC ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; END OF PROGRAM 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. :107F000090403C7402F0A3747FF0A37459F0D22720 :107F1000C2B5C2B47519FFF14F7590F3D2B5C2B5B1 :107F2000751909F14F7590F3F1847590F3F184752B :107F300090F2F1847428F1737408F173F1467406B9 :107F4000F173740CE173C2B47401F17375190A759D :107F500018FFD518FDD519F722D2B4B4200050135C :107F6000C2B4B40C0280E1B40D0474808005B40A7C :107F70001D74C0F51AC444F0F590D2B5C2B5E51A27 :0F7F800044F0F590D2B5C2B5751814D518FD228E :00000001FF