;This code is listed here for entertainment value only, it should ;not be used for anything important. Do not use this for a saleable product. ;Feel free to pass this on to others in it's entirety. along with this message. ;No Guarantees implicit or otherwise are implied, your mileage may vary. $RB(0) $RB(1) $NOMOD51 INCLUDE(87C752.pdf) $INCLUDE(common.inc) ; Note: These timings may not be optimal, i.e. I might be wasting some time ; but thats pretty low on my priorities for this code. DB4 EQU 1 DB5 EQU 2 DB6 EQU 4 DB7 EQU 8 RW EQU 16 RS EQU 32 ONE_LINE EQU 0 TWO_LINE EQU DB7 F5x7 EQU 0 F5x10 EQU DB6 CINC EQU DB5 CDEC EQU 0 SHIFT EQU DB4 CURSOR EQU 0 msec15 EQU 6553 msec5 EQU 2185 msec4_1 EQU 1791 msec2 EQU 874 usec100 EQU 44 usec40 EQU 17 oute MACRO X MOV A,#X ACALL DISPLAY ENDM out MACRO X MOV A,#X MOV P3,A ORL A,B MOV P3,A ENDM EXTRN CODE(PUTCHAR) EXTRN CODE(HEXSTR) CLIBC SEGMENT CODE RSEG CLIBC PUBLIC INITLCD PUBLIC PUTLCD PUBLIC LONGWAIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; INITLCD ; Initialize the LCD display. ; B contains either EN or EN2 for each display ; ; Use DPH:DPL to get timings of up to 15 msecs. ; at 5.24288MHz 1 cycle = 2.28882usec. ; 15 msec / 2.28882 usec = 65534 cycles ; 5 msec / 2.28882 usec = 2185 cycles ; 4.1 msec / 2.28882 usec = 1791 cycles ; 2.0 msec / 2.28882 usec = 874 cycles ; 100 usec / 2.28882 usec = 44 cycles ; 40 usec / 2.28882 usec = 17 cycles ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; These sequences are highly lcd specific INITLCD: CLR EA ; Shut off interrups to avoid timing problems. sleep msec15 ; Warning sleep trashes ACC out (DB4 OR DB5) sleep msec5 ; Warning sleep trashes ACC out (DB4 OR DB5) sleep msec5 ; Warning sleep trashes ACC out (DB4 OR DB5) sleep msec5 ; Warning sleep trashes ACC oute DB5 oute DB5 ; should this be F5x10? oute (TWO_LINE OR F5x10) oute 0 oute (DB7 OR DB6 OR DB5 OR DB4) oute 0 oute DB4 oute 0 oute (DB6 OR CINC OR CURSOR) SETB EA ; Turn interrupts back on. RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DISPLAY ; Writes raw byte in ACC ; AND toggles enable in B register no translation is done. ; R6 is used as loop counter for timing. DISPLAY: MOV P3,A ORL A,B MOV P3,A ;sleep for 2 msec. MOV R6,#(msec2/4) DJNZ R6,$ MOV R6,#(msec2/4) DJNZ R6,$ XRL A,B MOV P3,A RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; PUTLCD ; Writes character in ACC to the LCD display, ; Characters are sent out a nibble at a time with controls using the high ; nibble. ; Map of ACC is [ E2 E RS RW ] [ DB7 DB6 DB5 DB4 ] ; Uses R6 for timings. PUTLCD: PUSH DPL PUSH DPH PUSH B MOV B,A ANL A,#LOW( NOT(EN OR EN2)) ; RW bit is low (read). JNB ACC.4,NOT_SPECIAL ; RW bit is high (write request) MOV A,#'D' ; Use D= format for data output. ACALL PUTCHAR MOV A,#'=' ; Use D= format for data output. ACALL PUTCHAR MOV A,B ANL A,#LOW( NOT(EN OR EN2)) ORL A,#0f ; Bring data lines high for a read. MOV P3,A ORL A,B ; Enable LCD MOV P3,A MOV A,P3 ; And read high nibble first SWAP A ANL A,#0f0h ; move high nibble to correct spot and save PUSH ACC MOV A,B ANL A,#LOW( NOT(EN OR EN2)) ORL A,#0f ; Bring data lines high for a read. MOV P3,A ORL A,B ; Enable LCD MOV P3,A MOV A,P3 ; And read low nibble finally ANL A,#0fh POP B ADD A,B ; Now ACC contains the byte data from display. MOV P3,#LOW( NOT(EN OR EN2)) ACALL HEXSTR SJMP RETPUTLCD ; Leave routine. NOT_SPECIAL: MOV P3,A MOV P3,B MOV P3,A RETPUTLCD: POP B POP DPH POP DPL RET ; Overhead is 2+2+1, loop time is 6 cycles LONGWAIT: INC DPTR ; 2 cycle MOV A,DPH ; 1 cycle ORL A,DPL ; 1 cycle JNZ LONGWAIT ; 2 cycles RET ; 1 cycle $EJECT END