; File: NewIOLCD.A51 Date: 07/09/92 ; ; /* (c) Copyright BLUE EARTH RESEARCH, MANKATO, MN 1992. */ ; /* All rights reserved. */ ; $ TITLE(NEW LCD SOFTWARE FOR I/O-24 MODULE) $ PW(93) PL(60) DATE(07-09-92) $ DEBUG ERRORPRINT XREF ; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ; º LCD DRIVER SOFTWARE FOR IMPLEMENTING 2x16 DISPLAY º ; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ; ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ ; ³ Written By: Thomas Bachmann ³ ; ³ Blue Earth Research, Mankato, MN 56001 ³ ; ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; ; NOTES: ; The following program can be used to initialize and write ; messages to most standard LCD Modules using the Micro-440 ; and I/O-24 module. It was tested using a Sharp LM16X21A ; 2 line by 16 character display. ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; BASIC program interface: ; The LCD is initialized by executing the following BASIC ; Statement: "CALL 7D00H" ; Messages are then displayed by calling the proper address, ; beginning with 7E00H for MSG1, 7E10H for MSG2, 7E20H for ; MSG3, etc. This can be demonstrated by the following BASIC ; Program: ; 100 CALL 7D00H : GOSUB 200 : REM WAIT FOR KEY PRESS ; 110 CALL 7E00H : GOSUB 200 : REM DISPLAY MSG1 ; 120 CALL 7E10H : GOSUB 200 : REM DISPLAY MSG2 ; 130 CALL 7E20H : END : REM DISPLAY MSG3 ; 200 DO : A=GET : UNTIL A : RETURN ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $ EJECT ; Assembly language program interface: ; The LCD is addressed as it would be in BASIC, except that ; program labels can be used in the source file. For example, ; CALL INITIALIZE ; Initialize LCD Module ; CALL MSG1 ; Display first message ; ... ; Any other code goes here ; CALL MSG2 ; Repeat for all other messages ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; Troubleshooting hint: ; If your LCD module appears to reset properly but does not ; display characters, make sure that the contrast adjust ; potentiometer on the I/O-24 module is properly positioned. ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ DEFINITIONS SPECIFIC TO THE SYSTEM WIRING ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; The following software assume that the LCD module is ; wired with all inputs to Port A and Port B as follows: ; SIGNAL I/O-24 SIGNAL ; -------- ----------- -------- ; 13 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; DB7ÄÄÄÄÄÄÄÄÄÄÄ´ PA7 ³ ; 25 ³ ³ ; DB6ÄÄÄÄÄÄÄÄÄÄÄ´ PA6 ³ ; 12 ³ ³ ; DB5ÄÄÄÄÄÄÄÄÄÄÄ´ PA5 ³ ; 24 ³ ³ ; DB4ÄÄÄÄÄÄÄÄÄÄÄ´ PA4 ³ ; 11 ³ ³ ; DB3ÄÄÄÄÄÄÄÄÄÄÄ´ PA3 ³ ; 23 ³ ³ ; DB2ÄÄÄÄÄÄÄÄÄÄÄ´ PA2 ³ ; 10 ³ ³ ; DB1ÄÄÄÄÄÄÄÄÄÄÄ´ PA1 ³ ; 22 ³ ³ ; DB0ÄÄÄÄÄÄÄÄÄÄÄ´ PA0 ³ ; 9 ³ ³ 2 ; EÄÄÄÄÄÄÄÄÄÄÄÄ´ PB7 0-5 ÃÄÄÄÄÄÄÄÄÄÄÄVee ; 21 ³ ³ 14 ; R/WÄÄÄÄÄÄÄÄÄÄÄ´ PB6 +5V ÃÄÄÄÄÄÄÄÄÄÄÄVcc ; 8 ³ ³ 1 ; RSÄÄÄÄÄÄÄÄÄÄÄ´ PB5 GND ÃÄÄÄÄÄÄÄÄÄÄÄVss ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ $ EJECT ; ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ ; ³ PARAMETER DEFINITIONS ³ ; ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; ; All registers, bits, addresses, and constants are declared ; below. The program can be adapted to system wiring or ; parameter changes by modifying the corresponding definition ; located in the following code block. DSEG AT 18H LCD_CHAR: DS 1 ; HOLDS THE NEXT LCD CHARACTER CLOCK1: DS 2 ; TIMER REGISTERS FOR WAITING EXEC_TIME EQU 60 ; INSTRUCTION EXECUTION TIME COMMAND EQU 1110$0000B ; ALL SIGNALS LOW DATA_OUT EQU 1100$0000B ; SELECT DD RAM CLOCK_COMMAND EQU 0110$0000B ; TOGGLE 'E' SIGNAL CLOCK_DATA EQU 0100$0000B ; TOGGLE 'E' SIGNAL RESET EQU 0011$0000B ; "RESET" BYTE FUNCTION_SET EQU 0011$1000B ; "FUNCTION SET" BYTE DISPLAY_OFF EQU 0000$1000B ; "DISPLAY OFF" BYTE DISPLAY_ON EQU 0000$1100B ; "DISPLAY ON" BYTE ; NOTE: 0000$11cbB For "Display On," where ; c=1 for Cursor on, and b=1 for blinking cursor CLEAR_DISPLAY EQU 0000$0001B ; "CLEAR DISPLAY" BYTE MODE_SET EQU 0000$0110B ; "ENTRY MODE" BYTE LINE2 EQU 1100$0000B ; "GOTO LINE 2" BYTE LINE1 EQU 1000$0000B ; "GOTO LINE 1" BYTE SHIFT_RIGHT EQU 0001$1100B ; "SHIFT DISPLAY RIGHT" SHIFT_LEFT EQU 0001$1000B ; "SHIFT DISPLAY LEFT" CURSOR_LEFT EQU 0001$0000B ; "SHIFT CURSOR LEFT" CURSOR_RIGHT EQU 0001$0100B ; "SHIFT CURSOR RIGHT" ; Initialize the 82C55 Control Word as follows: ; PORT A = OUTPUT PORT C(0-3) = OUTPUT ; PORT B = OUTPUT PORT C(4-7) = INPUT ; Note: For more information, see Page 3-107 in Intel Data ; Book #296467-002, "1991 Peripheral Components" CONTROL_WORD EQU 1000$1000B ; SELECT MODE 0 CONTROL EQU 0FB00H ; SET BOTH A0 & A1 PORT_C EQU 0FA00H ; SET A1 ONLY PORT_B EQU 0F900H ; SET A0 ONLY PORT_A EQU 0F800H ; NEITHER A0 NOR A1 RESET_HIGH EQU 0E200H ; RESET SIGNAL HIGH RESET_LOW EQU 0E000H ; RESET SIGNAL LOW ; ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ ; ³ BEGINNING OF INITIALIZATION ROUTINE ³ ; ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; CSEG AT 7D00H INITIALIZE: MOV DPTR,#RESET_HIGH MOVX @DPTR,A ; HOLD RESET LINE HIGH MOV CLOCK1,#25 ; LOAD 50 uS LOOP COUNT DJNZ CLOCK1,$ MOV DPTR,#RESET_LOW MOVX @DPTR,A ; INITIALIZE 82C55 PORTS A & B AS OUTPUTS MOV DPTR,#CONTROL MOV A,#CONTROL_WORD MOVX @DPTR,A LCDSTART: ; LCD display initialization routine MOV DPTR,#PORT_B MOV A,#COMMAND ; CLEAR ALL CONTROL LINES MOVX @DPTR,A MOV CLOCK1,#30 ; WAIT FOR A LONG TIME CALL WAIT_LONG MOV DPTR,#PORT_A MOV A,#RESET ; WRITE BYTE MOVX @DPTR,A MOV DPTR,#PORT_B MOV A,#CLOCK_COMMAND MOVX @DPTR,A ; CLOCK IT IN SETB ACC.7 MOVX @DPTR,A ACALL LD_DEC ; WAIT AT LEAST 4.1 mS MOV A,#RESET ; WRITE BYTE ACALL CLOCK_N_WAIT MOV A,#RESET ; WRITE BYTE ACALL CLOCK_N_WAIT MOV A,#FUNCTION_SET ; WRITE BYTE ACALL CLOCK_N_WAIT ; CLOCK IT IN $ EJECT ; Output the byte that specifies an 8-bit interface MOV DPTR,#PORT_B ; SET CONTROL LINES MOV A,#COMMAND MOVX @DPTR,A ; SELECT COMMAND MOV A,#FUNCTION_SET ; GET THE BYTE ACALL CLOCK_N_WAIT ; CLOCK IT IN ; Turn the dispay off MOV DPTR,#PORT_B ; SET CONTROL LINES MOV A,#COMMAND MOVX @DPTR,A ; SELECT COMMAND MOV A,#DISPLAY_OFF ; GET THE BYTE ACALL CLOCK_N_WAIT ; CLOCK IT IN ACALL CLEAR ; CLEAR THE DISPLAY ; SET THE DISPLAY ENTRY MODE MOV DPTR,#PORT_B ; SET CONTROL LINES MOV A,#COMMAND MOVX @DPTR,A ; SELECT COMMAND MOV A,#MODE_SET ; GET THE BYTE ACALL CLOCK_N_WAIT ; CLOCK IT IN ; TURN THE DISPLAY BACK ON MOV DPTR,#PORT_B ; SET CONTROL LINES MOV A,#COMMAND MOVX @DPTR,A ; SELECT COMMAND MOV A,#DISPLAY_ON ; GET THE BYTE ACALL CLOCK_N_WAIT ; CLOCK IT IN ; MAKE SURE THAT THE CONTRAST ADJUST WILL WORK MOV DPTR,#PORT_C MOV A,#0F0H ; WRITE 1's TO INPUT PORT MOVX @DPTR,A AJMP CLEAR ; CLEAR DISPLAY AND RETURN $ EJECT ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ DISPLAY WRITING SUBROUTINES ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; Output the command byte in the Accumulator and wait. CLOCK_N_WAIT: MOV DPTR,#PORT_A ; POINT TO DATA LINES MOVX @DPTR,A ; OUTPUT THE BYTE MOV DPTR,#PORT_B ; POINT TO CONTROL LINES MOV A,#CLOCK_COMMAND ; SET 'E' HIGH MOVX @DPTR,A SETB ACC.7 MOVX @DPTR,A ; AND CLEAR 'E' MOV CLOCK1+1,#EXEC_TIME ; WAIT AT LEAST 120 uS DJNZ CLOCK1+1,$ RET ; Clear the LCD display CLEAR: MOV DPTR,#PORT_B ; SET CONTROL LINES MOV A,#COMMAND MOVX @DPTR,A ; SELECT COMMAND MOV A,#CLEAR_DISPLAY ; GET THE BYTE ACALL CLOCK_N_WAIT ; CLOCK IT IN LD_DEC: MOV CLOCK1,#10 ; WAIT AT LEAST 4.9 mS WAIT_LONG: MOV CLOCK1+1,#250 DJNZ CLOCK1+1,$ DJNZ CLOCK1,WAIT_LONG RET $ EJECT ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ OUTPUT THE CHARACTER IN THE BUFFER REGISTER ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ OUT: MOV DPTR,#PORT_B ; SET CONTROL LINES MOV A,#DATA_OUT MOVX @DPTR,A ; SELECT DATA MOV A,LCD_CHAR ; GET THE BYTE CLOCK_THE_DATA: MOV DPTR,#PORT_A ; POINT TO DATA LINES MOVX @DPTR,A ; OUTPUT THE BYTE MOV DPTR,#PORT_B ; POINT TO CONTROL LINES MOV A,#CLOCK_DATA ; SET 'E' HIGH MOVX @DPTR,A SETB ACC.7 MOVX @DPTR,A ; AND CLEAR 'E' MOV CLOCK1+1,#EXEC_TIME ; WAIT AT LEAST 120 uS DJNZ CLOCK1+1,$ RET DISPLAY: PUSH DPL ; SAVE IT PUSH DPH SEND_IT:POP DPH ; LOAD THE POINTER POP DPL MOVX A,@DPTR ; GET THE NEXT CHARACTER MOV LCD_CHAR,A ; SAVE IT CJNE A,#'"',SEND_MORE ; CHECK FOR EOF CHARACTER RET SEND_MORE: ; OUTPUT THE CHARACTER TO THE LCD INC DPTR ; POINT TO THE NEXT CHARACTER PUSH DPL ; SAVE THE POINTER PUSH DPH ACALL OUT ; SEND IT OUT SJMP SEND_IT $ EJECT ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ WRITE MESSAGES TO THE LCD ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ CSEG AT 7E00H ; THESE ADDRESSES CAN BE CALLED FROM BASIC TO DISPLAY THE ; CORRESPONDING MESSAGE. MSG1: ACALL CLEAR MOV DPTR,#STR1 ; POINT TO CHARACTER STRING ACALL DISPLAY MOV A,#LINE2 ACALL CLOCK_N_WAIT MOV DPTR,#STR1A ; POINT TO NEXT STRING SJMP DISPLAY MSG2: ACALL CLEAR MOV DPTR,#STR2 ; POINT TO CHARACTER STRING ACALL DISPLAY MOV A,#LINE2 ACALL CLOCK_N_WAIT MOV DPTR,#STR2A ; POINT TO NEXT STRING SJMP DISPLAY MSG3: ACALL CLEAR MOV DPTR,#STR3 ; POINT TO CHARACTER STRING ACALL DISPLAY MOV A,#LINE2 ACALL CLOCK_N_WAIT MOV DPTR,#STR3A ; POINT TO NEXT STRING SJMP DISPLAY $ EJECT ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ CHARACTER STRING DEFINITIONS ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ STR1: DB 'Blue Earth"' STR1A: DB 'Research"' STR2: DB ' Micro-440"' STR2A: DB 'Demonstration"' STR3: DB 'Put ANY"' STR3A: DB 'Message Here"' ; 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. :107D000090E200F0751919D519FD90E000F090FB94 :107D1000007488F090F90074E0F075191E127D90DF :107D200090F8007430F090F9007460F0D2E7F0B190 :107D30008D7430B16F7430B16F7438B16F90F900D9 :107D400074E0F07438B16F90F90074E0F07408B129 :107D50006FB18390F90074E0F07406B16F90F90090 :107D600074E0F0740CB16F90FA0074F0F0A183909D :107D7000F800F090F9007460F0D2E7F0751A3CD585 :107D80001AFD2290F90074E0F07401B16F75190AC0 :107D9000751AFAD51AFDD519F72290F90074C0F0BA :107DA000E51890F800F090F9007440F0D2E7F07513 :107DB0001A3CD51AFD22C082C083D083D082E0F560 :0E7DC00018B4220122A3C082C083B19A80ECC5 :107E0000B183907E30B1B674C0B16F907E3B80A6D6 :107E1000B183907E44B1B674C0B16F907E508096AD :107E2000B183907E5EB1B674C0B16F907E6680867D :107E3000426C756520456172746822526573656194 :107E40007263682220204D6963726F2D34343022B2 :107E500044656D6F6E7374726174696F6E225075D4 :107E60007420414E59224D657373616765204865E2 :037E700072652216 :00000001FF