;***************************************** ;******LCD-Treiber-C-kompatibel*********** ;***************************************** ;letzte Änderung: /*****************************************************************************/ /*Anpassung an EA DIP204B-4NLW Display mit KS0073 Controller (4x20 Zeichen) */ /*neue Funktion: clr_lcd --> löscht alle 4 Zeilen */ /*die Timings wurden optimiert --> schnellere Ausgabe auf LC-Display */ /* */ ;====================== Unterprogramme(Funktionen)================================= ; ; clr_lcd: Löscht alle 4 Zeilen ; init_display: Initialisierung des LC-Displays ; _printchar: Gibt das Zeichen in R7 auf dem Diaplay in ASCII aus ; _print_hex: Gibt die Zahl in R7 in HEX auf dem Display aus (00 bis FF) ; _print_lcd: Schreibt einen String auf das Display (ab Label "TEXT", Ende: 00h) ; _moveto: bewegt Cursor an Displayposition (R7->Zeile,R5->Spalte) ; cursor_off: Cursor unsichtbar ; cursor_on: Cursor sichtbar ; _print_digit: Inhalt von R7 wird als dreistellige Dezimalzahl ausgegeben ;==================================================================================== ;Hilfs-Unterprogramme ; SR_Check_Busy: Prüft ob Display noch beschäftigt (Busy-Flag) ; SR_Command: Schreibt ein Kommando an das Display (Akku) ;==================================================================================== $NOMOD51 ;Ausschalten der Reg51.inc(sonst Fehlermeldung) #include ;Registerdef. #include ;Die Einsprunglabels der Unterprogramme PUBLIC _printchar ;werden als PUBLIC deklariert und können PUBLIC init_display ;in anderen Modulen verwendet werden PUBLIC _print_hex PUBLIC _print_lcd PUBLIC _moveto PUBLIC SR_Command PUBLIC cursor_off PUBLIC cursor_on PUBLIC _print_digit PUBLIC clr_lcd ?PR?LCD SEGMENT CODE ;"?PR?LCD" ist Name eines rel. Codesegments RSEG ?PR?LCD ;und beginnt ab hier ;Display löschen clr_lcd: mov a,#0x01 ;Clear Display lcall SR_Command lcall del4100us ret ;============================================================================== ;***********Unterprogramme***************************************************** ;============================================================================== ; Stringausgabe auf Display ;============================================================================== ; Übergabewert: dptr in R7(LSB), R6(MSB) ; Ergebnis: -- ; verw. Reg.: DPTR, ACC, R7 ;============================================================================== ; Bemerkungen: Der String muß mit '0' terminiert sein ;============================================================================== _print_lcd: push ACC push PSW mov dph,R6 mov dpl,R7 LAB_Print2: mov A,#0 movc A,@A+DPTR mov R7,A cjne A,#0,LAB_Print1 pop PSW pop ACC ret LAB_Print1: lcall _printchar inc DPTR sjmp LAB_Print2 ;=========================================================================== ; HEX-Ausgabe einer Zahl auf dem Display ;============================================================================= ; Parameter: R7 enthält char-Zahl ; Ergebnis: --- ; verw. Reg.: --- ; glob. Var.: --- ;============================================================================= ; Bemerkungen: Die 8-Bit Zahl in R7 ; wird an der aktuellen Position als XX-Hex im Display ausgegeben. ;============================================================================= _print_hex: push ACC push PSW push 7 mov A,7 push ACC swap A anl A,#0fh ; High-Nibble ausmaskieren clr C ; subb A,#10 ; jc M_Pr_BCD_ok1 ; add A,#7 M_Pr_BCD_ok1: add A,#('0'+10) mov 7,A lcall _printchar ;high-Nibble fertig. ; pop ACC ; anl A,#0fh ; low-Nibble ausmaskieren clr C ; subb A,#10 ; jc M_Pr_BCD_ok2 add A,#7 M_Pr_BCD_ok2: add A,#('0'+10) mov 7,A lcall _printchar pop 7 pop PSW pop ACC ret ;============================================================================== ; Ausgabe eines Characters an der aktuellen Cursorposition ;============================================================================== ; Aufruf: R7 enthält Character ; Ergebnis: -- ; verw. Reg.: -- ;============================================================================== ; Bemerkungen: ;============================================================================== _printchar: push PSW push ACC mov A,7 push ACC lcall SR_Check_Busy mov Display,#0 setb Display_RS clr DISPLAY_RW; anl A,#0f0h orl Display,A setb Display_E nop nop nop clr Display_E mov Display,#0 setb Display_RS pop ACC swap a anl A,#0f0h orl Display,A setb Display_E nop nop nop clr Display_E pop ACC pop PSW lcall del100us //lcall del4100us ret ;============================================================================== ; Routine zur Ausgabe eines Kommandos an ein Display ;============================================================================== ; Aufruf: Kommando im ACC ; Ergebnis: -- ; verw. Reg.: -- ;============================================================================== ; Bemerkungen: ;============================================================================== SR_Command: push PSW push ACC push ACC lcall SR_Check_Busy mov Display,#0 anl A,#0f0h orl Display,A setb Display_E nop nop nop clr Display_E mov Display,#0 pop ACC swap a anl A,#0f0h orl Display,A setb Display_E nop nop nop clr Display_E pop ACC pop PSW lcall del100us //lcall del4100us ret ;============================================================================== ; Bewegt Cursor zu den geforderten Koordinaten im Display ;============================================================================== ; Aufruf: R7 enthält Zeile (0,1), R5 enthält Spalte (0..40) ; Ergebnis: -- ; verw. Reg.: -- ;============================================================================== ; Bemerkungen: R7 enthält Zeile (0..1), R5 enthält Spalte (0..40d) ;============================================================================== _moveto: push 0 push ACC push B push PSW mov A,R7 mov B,#20h mov c,ACC.1 ;Bei Zeile 3 oder 4 ist 2.Bit = 1 JC Zeile ;somit spring zu Zeile mul AB add A,R5 ljmp Ende Zeile: clr c subb A, #01h mul AB add A,R5 add A,#20h ;und addiere 0x20 dazu Ende: setb ACC.7 lcall SR_Command pop PSW pop B pop ACC pop 0 ;=============================================================== ; ;============================================================================== ; Warten, bis Display bereit für nächsten Befehl ;============================================================================== ; Aufruf: -- ; Ergebnis: Rücksprung, wenn Display nicht mehr Busy ; verw. Reg.: -- ;============================================================================== ; Bemerkungen: ;============================================================================== SR_Check_Busy: push PSW push Display mov Display,#0 setb Display_RW clr DISPLAY_RS LAB_Display_Busy: setb Display_E nop nop nop mov C,Display_busy ; erster Lesezyklus nop clr Display_E setb Display_E ; zweiter Lesezyklus nop nop nop clr Display_E jc LAB_Display_Busy clr DISPLAY_RW pop Display ; Wiederherstellen von RS und RnW pop PSW ret ;============================================================================== ; Initialisierung des Displays ;============================================================================== ; Aufruf: kein Parameter ; Ergebnis: keines ; verw. Reg.: ACC ;============================================================================== ; Bemerkungen: ;============================================================================== /*****************************************************************************/ */ /*****************************************************************************/ init_display: lcall del4100us lcall del4100us lcall del4100us mov Display,#0x30 ;Function set -8bit- nop setb DISPLAY_E nop nop nop clr DISPLAY_E lcall del4100us lcall del4100us lcall del4100us mov Display,#0x30 nop setb DISPLAY_E nop nop nop clr DISPLAY_E lcall del4100us mov Display,#0x30 nop setb DISPLAY_E nop nop nop clr DISPLAY_E //Init 3 //Programmiermodus lcall del4100us mov Display,#0x20 ;Function Set: 4-Bit nop setb DISPLAY_E nop nop nop clr DISPLAY_E lcall del4100us mov a,#0x28 ;Function Set: 4 Bit, 2 Zeilen, 5x7 Punkte lcall SR_Command lcall del4100us mov a,#0x24 ;Function Set: 4 Bit, RE = 1 lcall SR_Command lcall del4100us mov a,#0x09 ;Extendet Function Set: 4 Zeilen, 5x7 Punkte lcall SR_Command lcall del4100us mov a,#0x20 ;Fuction Set: 4 Bit, 5x7 Punkte lcall SR_Command lcall del4100us mov a,#0x0C ;Display ein,Cursor aus lcall SR_Command lcall del4100us mov a,#0x01 ;Clear Display lcall SR_Command lcall del4100us mov a,#0x06 ;Entry Mode Set: Cursor wird inkrementiert lcall SR_Command lcall del4100us ret del100us: ;******************** ; Etwas warten (400 Cycles eq. 108us LPC) ; nutzt r7 (eq. 400us @12MhzLAB537 ) ;******************** mov r7,#200 del1: djnz r7,del1 ret del4100us: mov r6,#50 ;delay 5,5 ms(LPC) del2: lcall del100us djnz r6,del2 ret ret ;============================================================================== ; Cursor ein-/ausschalten ;============================================================================== ; Aufruf: kein Parameter ; Ergebnis: keines ; verw. Reg.: -- ;============================================================================== ; Bemerkungen: ;============================================================================== cursor_off: push ACC ; mov A,#0CH ; lcall SR_COMMAND ; pop ACC ; ret ; ; cursor_on: push ACC ; mov A,#0EH ; lcall SR_COMMAND ; pop ACC ; ret ; ;============================================================================= ; Bemerkungen: Die zweistellige BCD-Zahl, deren LSB durch R0 bestimmt wird, ; wird an der aktuellen Position im Display ausgegeben. ; Es wird vorher ein Leerzeichen ausgegeben. ;============================================================================= SR_Print_BCD: push 0 push ACC push PSW mov R0,A ; sichern swap A anl A,#0fh ; low-Nibble ausmaskieren add A,#'0' lcall _printchar mov A,R0 anl A,#0fh ; low-Nibble ausmaskieren add A,#'0' lcall _printchar pop PSW pop ACC pop 0 ret ;*********************************************************** ;SUBROUTIN _print_digit ;************************************************************ /*****************************************************************************/ */ /*****************************************************************************/ _print_digit: PUSH PSW PUSH B PUSH ACC ;UEBERGABE AKKU mov A,R7 /* MOV B,#100 ;ACC := (ACC DIV B)+48 DIV AB ADD A,#48 mov R7,A LCALL _printchar ;WRITE 100 MOV A,B ;ACC := (ACC DIV B)+48 */ MOV B,#10 DIV AB ADD A,#48 mov R7,A LCALL _printchar ;WRITE 10 MOV A,B ;ACC := ACC + 48 ADD A,#48 mov R7,A LCALL _printchar ;WRITE 1 POP ACC ;RESTORE REGISTERS POP B POP PSW RET END