EJECT ;=============================================================================== ; LCD Driver 2.04.2007 ;------------------------------------------------------------------------------- Public LCD_Set , LCD_Out Public LCD_Init, LCD_CLS Public LCD_Show, LCD_Char Public GetCursorPos, SetCursorPos Public GetKey, GetLCD Public ReadKey Public AtoH, BtoH, NtoA, BtoD Public Wait_A10ms, Wait10ms Public DPTRx10, DPTR_A Public KEY_Buffer Extrn XTAL Extrn LCD_Port ;------------------------------------------------------------------------------- Out Macro Value MOV A, Value Call LCD_Out EndM Set Macro Value MOV A, Value Call LCD_Set EndM XY_POS Macro PosX, PosY ;X[0..19],Y[0..3] MOV A, #80H+PosX+((PosY&1)*40H)+((PosY&2)*10) CALL LCD_Set EndM XY_MSG Macro PosX, PosY, Value Cond (PosX>=0)&(PosX<20)&(PosY>=0)&(PosY<4) XY_POS PosX, PosY EndC Call LCD_Show DC Value EndM Hex Macro Value Mov A, Value Call BtoH EndM Wait Macro Value MOV A, Value Call Wait_A10ms EndM ;=============================================================================== ; List off Include MACROS.INC ;------------------------------------------------------------------------------- ;Anschaltung ;Port : 7 6 5 4 3 2 1 0 ;LCD : D7 D6 D5 D4 RW RS -- LE ;KEY : K6 K5 K4 K3 K2 K1 KE -- ; 6 Tasten mit Diode, Kathoden an KE ; ;Display, CursorPos = X+(Y&1*40H)+(Y&2*10) ; Spalte 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 ;0.Zeile 00H 01H 02H 03H 04H 05H 06H 07H 08H 09H 0AH 0BH 0CH 0DH 0EH 0FH 10H 11H 12H 13H ;1.Zeile 40H 41H 42H 43H 44H 45H 46H 47H 48H 49H 4AH 4BH 4CH 4DH 4EH 4FH 50H 51H 52H 53H ;2.Zeile 14H 15H 16H 17H 18H 19H 1AH 1BH 1CH 1DH 1EH 1FH 20H 21H 22H 23H 24H 25H 26H 27H ;3.Zeile 54H 55H 56H 57H 58H 59H 5AH 5BH 5CH 5DH 5EH 5FH 60H 61H 62H 63H 64H 65H 66H 67H ; ;------------------------------------------------------------------------------- ; @R0 = CurPos ((0)=X[0..19]|(1)=Y[0..3]) ; kill C Cond ?GetCursorPos GetCursorPos: MOV LCD_Port,#1111 1010B ;read LCD, Key off Push A SETB LCD_Port.0 Inc R0 MOV A, #70H ANL A, LCD_Port CLR LCD_Port.0 Push B SETB LCD_Port.0 Mov B, A MOV A, #0F0H ANL A, LCD_Port MOV LCD_Port,#1111 0010B Swap A Orl A, B ;AC6..AC0 Mov B, #40H DIV AB ;if Y in [1,3] then A=1 Mov @R0, A MOV A, B Mov B, #14H Div AB ;B = X (0..19) RL A ;if Y in [2,3] then A=2 Add A, @R0 Mov @R0, A ;(1)=Y Dec R0 Mov A, B Mov @R0, A ;(0)=X Pop B,A Ret EndC ;------------------------------------------------------------------------------- ; A = CurPos = @R0 ((0)=X[0..19]|(1)=Y[0..3]) ; kill C Cond ?SetCursorPos SetCursorPos: Push B Inc R0 MOV A, @R0 ANL A, #1 RR A RR A ;ord(Y and 1) * 40H Push A Mov A, @R0 ANL A, #2 MOV B, #10 Mul AB ;ord(Y and 2) * 14H POP B Add A, B POP B Dec R0 Add A, @R0 ;Line[Y] + X Orl A, #80H Push A Call LCD_Set POP A RET EndC ;------------------------------------------------------------------------------- ; Charakter in LCD schreiben ;Aufruf: Call LCD_Char ; DB L1,L2,L3,L4,L5,L6,L7,L8+80H Cond ?LCD_Char LCD_Char: Set #40H EndC ;------------------------------------------------------------------------------- ; Ausgabe Zeichenkette bis Char.7=1 ;Aufruf: Call LCD_Show ; DC 'String' Cond ?LCD_Show | ?LCD_Char LCD_Show: POP DPTR LCD_String1: CLR A MOVC A, @A+DPTR INC DPTR JBC A.7, LCD_String2 CALL LCD_Out JMP LCD_String1 LCD_String2: CALL LCD_Out CLR A JMP @A+DPTR ;Return to program. EndC ;------------------------------------------------------------------------------- Cond ?GetLCD GetLCD: Call IfBusy MOV LCD_Port, #1111 1110B Push B SETB LCD_Port.0 MOV A, #1111 0000B Anl A, LCD_Port ;D7..D4 CLR LCD_Port.0 Mov B, A SETB LCD_Port.0 MOV A, #1111 0000B Anl A, LCD_Port ;D3..D0 CLR LCD_Port.0 Swap A Orl A, B Pop B Ret EndC ;------------------------------------------------------------------------------- Cond ?LCD_Init LCD_Init: Mov LCD_Port, #1111 1010B ;read LCD, Key off Wait #10 Set #0010 1000B ;Modus 4bit Set #0000 1100B ;Display on, Cursor off EndC ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cond ?LCD_Init | ?LCD_CLS LCD_CLS: MOV A, #00000001B ;Display clear, Cursor home and off EndC ;------------------------------------------------------------------------------- Cond ?LCD_Set | ?LCD_CLS | ?LCD_Init ; Command A to LCD LCD_Set: Call IfBusy CLR LCD_Port.2 JMP Wr8Bit EndC ;------------------------------------------------------------------------------- Cond ?LCD_Out | ?Wr8Bit ; OUT A to LCD LCD_Out: Call IfBusy SetB LCD_Port.2 ;RS Wr8Bit: CALL Wr4Bit Wr4Bit: ANL LCD_Port, #0000 0110B PUSH A ANL A,#1111 0000B ORL LCD_Port, A POP A SWAP A WrPuls: SETB LCD_Port.0 CLR LCD_Port.0 RET EndC Cond ?IfBusy IsBusy: CLR LCD_Port.0 SETB LCD_Port.0 IfBusy: MOV LCD_Port,#1111 1010B ;read LCD, Key off SETB LCD_Port.0 JB LCD_Port.7, IsBusy ;D7-D4 CLR LCD_Port.0 JMP WrPuls ;D3-D0 EndC ;------------------------------------------------------------------------------- ;XTal & 12Cyclen ~> 10ms Cond ?Wait10ms Wait10ms: Push A, B Mov A, #XTAL/552960 Wait10Loop: Mov B, #228 Djnz B, $ DJNZ ACC, Wait10Loop POP B, A Ret EndC ;------------------------------------------------------------------------------- ;Wait A*10ms Cond ?Wait_A10ms Wait_A10ms: Call Wait10ms DJNZ ACC, Wait_A10ms Ret EndC ;------------------------------------------------------------------------------- ;Tastenabfrage COND ?GetKey ; Key LCD GetKey: ; \ / MOV LCD_Port, #11111100B MOV A, #11110110B ;no read LCD XCH A, LCD_Port XCH A, KEY_Buffer ORL A, KEY_Buffer ;Taste 2x hintereinander RR A RR A CPL A ANL A, #00111111B RET EndC ;------------------------------------------------------------------------------- Cond ?ReadKey ; A := [Key] ; NotKeyPressed = 0 ; no Kill ReadKey: Mov LCD_Port, #1111 1100B PUSH B MOV B, #6 Mov A, #1111 0010B XCH A, LCD_Port JNB A.7, ReadKey3 ;ESC mit Vorrang CPL A ANL A, #1111 1100B ReadKey1: JBC A.7, ReadKey2 RL A DJNZ B, ReadKey1 ReadKey2: ;CLR A.7 JZ ReadKey3 MOV B, #0 ReadKey3: MOV A, B POP B RET EndC ;------------------------------------------------------------------------------- ;Output A as HexadezimalZahl ;no kill Cond ?BtoH BtoH: SWAP A CALL NtoA SWAP A EndC Cond ?NtoA NtoA: PUSH A ANL A, #00001111B ADD A, #90H DA A ADDC A, #40H DA A CALL LCD_Out POP A RET EndC ;------------------------------------------------------------------------------- ;Output A as DezimalZahl ;kill A,B Cond ?BtoD BtoD: MOV B,#100 CALL BtoD1 ; 10^2 MOV B,#10 CALL BtoD1 ; 10^1 JMP BtoD2 ; 10^0 BtoD1: DIV AB BtoD2: ORL A, #'0' CALL LCD_Out MOV A,B RET EndC ;------------------------------------------------------------------------------- ;Input A as HexadezimalZahl Cond ?AtoH AtoH: Clr C Subb A, #'0' CJL A, #10, AtoH1 ; 0..9, ready Add A, #-7 CJL A, #16, AtoH1 ; A..F, ready CLR A ; bad ASCII, return 00h AtoH1: Ret EndC ;------------------------------------------------------------------------------- ;Input A as DezimalZahl Cond ?AtoD AtoD: Clr C Subb A, #'0' CJL A, #10, AtoD1 ; 0..9, ready CLR A ; bad ASCII, return 00h AtoD1: Ret EndC ;------------------------------------------------------------------------------- ; DPTR = DPTR * 10 Cond ?DPTRx10 DPTRx10: Push B, A Mov A,DPL Mov B, #10 Mul AB ; BA = DPL * 10 Mov DPL, A Mov A, B XCH A, DPH ; B <-> DPH Mov B, #10 Mul AB ; BA = DPH * 10 ADD A, DPH Mov DPH, A Pop A, B Ret EndC ;------------------------------------------------------------------------------- ;DPTR = DPTR + A Cond ?DPTR_A DPTR_A: XCH A, DPL Add A, DPL JnC DPTR_A1 INC DPH DPTR_A1: XCH A, DPL Ret EndC ;------------------------------------------------------------------------------- ISEG Cond ?KEY_Buffer KEY_Buffer: DS 1 ; RAM for GetKey EndC CSEG ;------------------------------------------------------------------------------- END