LCD_PORT EQU P2 ;Port für LCD-Modul (HD44780 kompatibel) reg2 EQU 0Ah ;Register der Bank1 reg3 EQU 0Bh reg4 EQU 0Ch reg5 EQU 0Dh reg6 EQU 0Eh reg7 EQU 0Fh ;-------------------------------------- Display --------------------------------------- ; **************** Display initialisieren **************** ; ; Display arbeitet im 2*4-Bit Modus ; ; Die 16 Zeichen belegen die Display-Adressen 00-0F und 40-4F (HEX!) ; ; Bit: 7 6 5 4 3 2 1 0 ; Register Read/ 0 Takt D7/D3 D6/D2 D5/D1 D4/D0 ; Select Write initLCD: mov LCD_PORT,#00010011b ;aufwecken! Takt=1 mov LCD_PORT,#00000011b ; Takt=0 mov reg5,#10 ; ca. 5 msec warten w0: djnz reg4,w0 djnz reg5,w0 mov LCD_PORT,#00010011b ;aufwecken! Takt=1 mov LCD_PORT,#00000011b ; Takt=0 w2: djnz reg5,w2 ; wartet 100 usec mov LCD_PORT,#00010011b ;aufwecken! Takt=1 mov LCD_PORT,#00000011b ; Takt=0 w3: djnz reg5,w3 ; wartet 100 usec mov LCD_PORT,#00010010b ;8->4 BITS UMSCHALTEN, Takt=1 mov LCD_PORT,#00000010b ; Takt=0 w4: djnz reg5,w4 mov A,#00101000b ;Function set 4 bits lcall LCDbefehl ;Ausgabe im 4Bit-Modus mov A,#00001100b ; Display AN, Cursor AUS lcall LCDbefehl ;des Zeichens an der Cursorposition mov A,#00000110b ; Not Shifted Display, Increment lcall LCDbefehl ret ;*********** Loeschen Display ***************************************** loeschen: mov A,#00000001b ;Display clear lcall LCDbefehl ret ;*********** Cursor AN ************************************************ ;cursorAN: mov A,#00001110b ;Cursor und Display AN cursorAN: mov A,#00001111b ;Cursor blinkend und Display AN lcall LCDbefehl ret ;*********** Cursor AUS *********************************************** cursorAUS: mov A,#00001100b ;Cursor AUS, Display AN lcall LCDbefehl ret ;*********** Cursorposition ******************************************* cursorpos: orl a,#10000000b ;Kennung für DD RAM address set lcall LCDbefehl ret ;*********** Cursorhome *********************************************** ;cursorhome: mov A,#00000010b ;Cursor home ; lcall LCDbefehl ; ret ;*********** Zeile 1 löschen ****************************************** ;loeschzeile1: ; mov A,#00000010b ;Cursor home ; lcall LCDbefehl ; mov dptr,#textloesch ; lcall textzeile1 ; mov A,#00000010b ;Cursor home ; lcall LCDbefehl ; ret ;*********** Zeile 2 löschen ****************************************** ;loeschzeile2: ; mov a,#40h ; lcall cursorpos ;Cursor auf Position 1.Stelle/2.Zeile ; mov dptr,#textloesch ; lcall textzeile2 ; mov a,#40h ; lcall cursorpos ;Cursor auf Position 1.Stelle/2.Zeile ; ret ;*********** Text an Zeile 1 ausgeben ********************************* textzeile1: mov A,#00000010b ;Cursor home lcall LCDbefehl textaus2: mov reg4,#0 ;0 ins r4 => Buchstabe 0 textloop: mov A,reg4 ;Nr des Buchstabens in den Akku inc reg4 cjne a,#10h,holbuchst ;schon Maximalzahl an Buchstaben? sjmp textende ;für eine Zeile => ja => Ende holbuchst: movc A,@A+DPTR ;Text Buchstabenweise holen jz textende ;falls 0 => Ende, sonst ausgeben ausgeben: lcall LCDtext sjmp textloop textende: ret ;*********** Text an Zeile 2 ausgeben ********************************* textzeile2: mov a,#40h lcall cursorpos ;Cursor auf 1.Stelle/2.Zeile sjmp textaus ;********* Textaus (Text ab momentaner Cursorposition ausgeben ********** textaus: mov a,#0 movc a,@a+dptr ;Text zeichenweise holen jz textend ;Ende wenn Ordnungszahl des zeichens=0 lcall LCDtext inc dptr ;nächstes zeichen sjmp textaus textend: ret ;********* Befehl für LCD-Display im Akku ausgeben an LCD_PORT ************** ;*************** RS R/W D7 D6 D5 D4 D3 D2 D1 D0 ;*************** 0 0 x x x x x x x x LCDbefehl: push ACC swap a ;High- und Low-Nibbel tauschen anl A,#00001111b ;4 Bits maskieren orl A,#00010000b ;Übergabetakt = 1, High-Nibbel senden mov LCD_PORT,A anl A,#00001111b ;Takt = 0 mov LCD_PORT,A pop ACC anl A,#00001111b ;Low-Nibble orl A,#00010000b ;Takt = 1 mov LCD_PORT,A anl A,#00001111b ;Takt = 0 mov LCD_PORT,A sjmp wbusy ;warten bis Bearbeitung beendet ;********* Text fr LCD-Display im Akku ausgeben an LCD_PORT ************** ;*************** RS R/W D7 D6 D5 D4 D3 D2 D1 D0 ;*************** 1 0 x x x x x x x x LCDtext: push ACC swap a ;Nibbel vertauschen anl A,#00001111b ;4 Bits maskieren orl A,#10010000b ;Übergabetakt = 1, RS = 1 (Befehl!) mov LCD_PORT,A anl A,#10001111b ;Takt = 0 mov LCD_PORT,A pop ACC anl A,#00001111b ;Low-Nibble orl A,#10010000b ;Takt = 1, RS = 1 mov LCD_PORT,A anl A,#10001111b ;Takt = 0 mov LCD_PORT,A ;************** warten bis Bearbeitung im Display beendet ********** wbusy: mov LCD_PORT,#01011111b ; Busy lesen, Takt=1, RS = 0 mov A,LCD_PORT ; und holen mov LCD_PORT,#01001111b ; Takt=0 nop mov LCD_PORT,#01011111b ; Low-Byte holen (ohne Bedeutung) mov LCD_PORT,#01001111b mov reg2,50 ;Zeitverzögerung 1ms warteR2: mov reg3,#10 ;statt auf busy warten warteR3: djnz reg3,warteR3 ;wenn LCD an p0 djnz reg2,warteR2 ; jb ACC.3,wbusy ; Busy? warten , geht nicht mit LCD an p0 ret ;*********************** dez2aus ********************************************* ;+++++++++ Die Zahl im Akku wird als Dezimalzahl ausgegeben +++++++++++++++++ ;--------- Es werden immer 2 Stellen ausgegeben ----------------------------- dez2aus: push acc mov b,#10 ;wird durch 10 div ab ;geteilt swap a ;Die Zehnerziffer wird das High-Nibbel, add a,b ;die Einerziffer das Low-Nibbel mov reg5,a ;diese BCD-Zahl wird in r5 gespeichert mov a,reg5 ;2. u. 3. Ziffer zurückholen hex0: mov reg7,a ;zwischenspeichern in r7 anl a,#0f0h ;High-Nibbel maskieren swap a ;und zur Ziffer im Low-Nibbel machen lcall sendascii ;2.Ziffer ausgeben mov a,reg7 ;Zwischengespeicherte Zahl zurck anl a,#0fh ;Low-Nibbel ausblenden lcall sendascii ;und ausgeben dezend: pop acc ret ;*********************** dezaus ********************************************* ;+++++++++ Die Zahl im Akku wird als Dezimalzahl ausgegeben +++++++++++++++++ ;--------- Es werden immer 3 Stellen ausgegeben, führende Nullen sind dunkel ;dezaus: push acc ; mov b,#100 ;der in A stehende Wert wird durch 100 ; div ab ;geteilt und die Hunderter-Ziffer in ; mov reg7,a ;r7 gegeben ; mov a,b ;die verbleibende Zehnerzahl ; mov b,#10 ;wird durch 10 ; div ab ;geteilt ; swap a ;Die Zehnerziffer wird das High-Nibbel, ; add a,b ;die Einerziffer das Low-Nibbel ; mov reg5,a ;diese BCD-Zahl wird in r5 gespeichert ; mov a,reg7 ;die vorderste BCD-Ziffer ; mov reg4,a ;wird in r4 gesichert und ; jnz ausg1 ;wird normal ausgegeben, falls sie nicht 0 ist ; mov a,#31 ;leer2e Anzeige ; lcall lcdtext ;falls null ; sjmp Ziff2 ;ausg1: lcall sendascii ;1.Ziffer ausgeben ;Ziff2: mov a,reg5 ;2. u. 3. Ziffer zurückholen ;hex0: mov reg7,a ;zwischenspeichern in r7 ; anl a,#0f0h ;High-Nibbel maskieren ; swap a ;und zur Ziffer im Low-Nibbel machen ; jnz ausg2 ;wird normal ausgegeben, falls sie nicht 0 ist ; cjne a,reg4,ausg2 ;nur 0 unterdrücken falls 1.Ziffer auch 0 war ; mov a,#31 ;leer2e Anzeige ; lcall lcdtext ;falls null ; sjmp Ziff3 ;ausg2: lcall sendascii ;2.Ziffer ausgeben ;Ziff3: mov a,reg7 ;Zwischengespeicherte Zahl zurck ; anl a,#0fh ;Low-Nibbel ausblenden ; lcall sendascii ;und ausgeben ;dezend: pop acc ; ret ;*********************** hexaus ***************************************** ;+++++++++ Die Zahl im Akku wird hexadezimal ausgegeben +++++++++++++++++ ;--------- Es werden immer 2 Stellen mit führenden Nullen ausgegeben ---- hexaus: push acc mov reg7,a ;zwischenspeichern in r7 anl a,#0f0h ;High-Nibbel maskieren swap a ;und zur Ziffer im Low-Nibbel machen ; cjne a,#0,ausg2Z ;zur Unterdrückung der führenden Null ; mov a,#20 ;leer2e Anzeige ; lcall lcdtext ; sjmp weit2 ausg2Z: lcall sendascii weit2: mov a,reg7 ;Zwischengespeicherte Zahl zurck anl a,#0fh ;Low-Nibbel ausblenden lcall sendascii ;und ausgeben pop acc ret ;****************** dualaus (Zahl im Akku als 8-Bit-Dualzahl ausgeben) ******** dualaus: push acc mov reg5,#8 ;Zähler dloop: mov reg7,a ;Zahl zwischenspeichern jb acc.7,d1 ;Sprung zur "1"-Ausgabe wenn Bit=1 mov a,#0 ;Null ausgeben lcall sendascii sjmp d2 ; d1: mov a,#1 ;Eins ausgeben lcall sendascii d2: mov a,reg7 ;zwischengespeicherte Zahl zurück rl a ;nächstes Bit djnz reg5,dloop ;von vorne falls noch nicht alle 8 Bit pop acc ret ;***************** Duale Ausgabe rechtsbündig in Zeile 1 ********************* ;dualaus1: ; push acc ; mov a,#08 ; lcall cursorpos ; pop acc ; lcall dualaus ; ret ;***************** Duale Ausgabe rechtsbündig in Zeile 2 ********************* ;dualaus2: ; push acc ; mov a,#48 ; lcall cursorpos ; pop acc ; lcall dualaus ; ret ;************** sendascii (1 Hexziffer als Ascii-Zeichen senden) ********* sendascii: mov reg6,a subb a,#0Ah mov a,reg6 jc zahl Buchst: add a,#37h sjmp weit1 zahl: clr c ;Carry zurÜcksetzen, sonst Fehler bei add add a,#30h weit1: lcall LCDtext ret ;*************** zifferaus (eine Ziffer 0 bis 9 ausgeben ***************** zifferaus: push acc anl a,#0Fh lcall sendascii pop acc ret ;****** PIN-Belegung für LCD-Display LTN 214 R-10 am LCD_PORT ************** ; * Uebertragung eines Bytes als 2 * 4 Bits. ; * Ansicht von oben auf Display ; * 1 GND--------------------------------------------------> GND ; * 2 +5Volt-----------------------------------------------> +5V ; * 3 V0: Steuerspannung Kontrast 0..5 Volt erlaubt,-------> V0 ; * Arbeitspunkt ca. 0.6 V (am besten Spindeltrimmer zum Einst.) ; * 4 RS: Registersatz (Display oder Befehl)---------------> LCD_PORT.7 ; * 5 R/W: Schreiben oder lesen----------------------------> LCD_PORT.6 ; * 6 E: Uebergabetakt-------------------------------------> LCD_PORT.4 ; * 7-10: frei (eigentlich D0 - D3, wird aber nicht verwendet) ; * 11: D4/D0----------------------------------------------> LCD_PORT.0 ; * 12: D5/D1----------------------------------------------> LCD_PORT.1 ; * 13: D6/D2----------------------------------------------> LCD_PORT.2 ; * 14: D7/D3----------------------------------------------> LCD_PORT.3 ; ******************************************************* ;Auszugebene Texte textloesch: DB ' ',0 leer: db ' ',0 leer2: db ' ',0 punkt: db '.',0 doppelpunkt: db ':',0 strich: db ' - ',0 strich2: db '-',0 next: db 'next:',0 Textuhr: db ' Uhrzeit',0 Textuhrstellen: db ' Uhrzeit stellen:',0 Textkalender: db ' Datum stellen:',0 Text1: db ' Licht 1 (dimm+1)',0 Text2: db ' Licht 2 (dimm+2)',0 Text3: db ' Licht 3 (3)',0 Text4: db ' Licht Algen (4)',0 Text5: db ' Futterp. (5-10)',0 Text6: db ' Stroemung (5+6)',0 Textnachtlicht: db ' Nachtlicht:',0 Textdimm2: db ' 1) Dimmdauer 2)',0 Montag: db 'Mo.',0 Dienstag: db 'Di.',0 Mittwoch: db 'Mi.',0 Donnerstag: db 'Do.',0 Freitag: db 'Fr.',0 Samstag: db 'Sa.',0 Sonntag: db 'So.',0 Textmondsim: db 'Mondlichtsim.',0 Texth: db 'h',0 Textmin: db 'min',0