;**************************************************************************************** ;** LCD-Routine ;** ;** PC0-PC3: Datenleitungen ;** PC4 : Enable-Leitung ;** PC5 : RS-Leitung ;** ;** !!! DIE DELAYZEITEN SIND FÜR 4MHz CPU_TAKT BERECHNET !!! ;** ;** !!! in die Hauptdatei einfügen !!! ;** ;** .equ LCD_PORT = PORTc ; PORTc als LCD-PORT definieren für einfachen wechsel ;** .equ LCD_DDR = DDRc ; Datenregister c = Ausgang ;** .equ RS_BIT = 16 ; RS Pin ist Pin 4 => 2°4 = 16 ;** .equ Enable = 5 ; Enable Pin ist Pin 5 ;** ;** !!! in die Hauptdatei einfügen !!! ;** ;**************************************************************************************** LCD_Init: ldi temp, 50 powerupwait: rcall delay_5m dec temp brne powerupwait ldi temp, 0b00000010 ; 4 Bit-Modus einstellen out LCD_PORT, temp rcall LCD_Enable rcall delay_5m ldi temp, 0b00101000 ; 4 Bit, 2 Zeilen, 5*7 Dots rcall LCD_Senden ldi temp, 0b00001100 ; Display an, Cursor aus, Cursor blinkt nicht rcall LCD_Senden ldi temp, 0b00000110 ; inkrementieren, Cursor bewegen rcall LCD_Senden ret ;**************************************************************************************** LCD_Home: push temp ldi temp, 0b00000010 ; Cursor at Home rcall LCD_Senden rcall delay_5m pop temp ret ;**************************************************************************************** LCD_Clear: push temp ldi temp, 0b00000001 ; Code siehe Datenblatt rcall LCD_Senden rcall delay_5m pop temp ret ;**************************************************************************************** LCD_Daten: ;RS = 1 // temp wird übergeben push temp push temp1 mov temp1, temp ; temp sichern swap temp1 ; Nibbles vertauschen andi temp1, 0b00001111 ; oberes Nibble verunden sbr temp1, RS_BIT ; RS setzen out LCD_PORT, temp1 ; oberes Nibble ausgeben rcall LCD_Enable andi temp, 0b00001111 ; unteres Nibble verunden sbr temp, RS_BIT ; RS setzen out LCD_PORT, temp ; unteres Nibble ausgeben rcall LCD_Enable rcall delay_100u pop temp1 pop temp ret ;**************************************************************************************** LCD_Senden: ;RS = 0 // temp wird übergeben push temp push temp1 mov temp1, temp ; temp sichern swap temp1 ; Nibbles vertauschen andi temp1, 0b00001111 ; oberes Nibble verunden out LCD_PORT, temp1 ; oberes Nibble ausgeben rcall LCD_Enable andi temp, 0b00001111 ; unteres Nibble verunden out LCD_PORT, temp ; unteres Nibble ausgeben rcall LCD_Enable rcall delay_100u pop temp1 pop temp ret ;**************************************************************************************** LCD_Enable: ;E = 1 Daten werden von LCD-Kontroller übernommen sbi LCD_PORT, ENABLE ; Enable_Bit setzen nop ; Wartezeit (abhängig von CPU_FREQ) nop nop cbi LCD_PORT, ENABLE ; Enable-Bit löschen ret ;**************************************************************************************** lcd_number:; Übergabe der Zahl in temp push temp ; die Funktion verändert temp und temp1, push temp1 ; also sichern wir den Inhalt, um ihn am Ende ; wieder herstellen zu können mov temp1, temp ; das Register temp1 frei machen ; abzählen wieviele Hunderter ; in der Zahl enthalten sind ;** Hunderter ** ldi temp, '0'-1 ; temp1 mit ASCII '0'-1 vorladen rjmp lcd_number_2 // eingefügt weil ich für die uhr nur 2 Stellen brauche lcd_number_1: inc temp ; ASCII erhöhen (somit ist nach dem ersten ; Durchlauf eine '0' in temp1) subi temp1, 100 ; 100 abziehen brcc lcd_number_1 ; ist dadurch kein Unterlauf entstanden? ; nein, dann zurück zu lcd_number_1 subi temp1, -100 ; 100 wieder dazuzählen, da die ; vorherhgehende Schleife 100 zuviel ; abgezogen hat rcall LCD_DATEN ; die Hunderterstelle ausgeben ;** Zehner ** ldi temp, '0'-1 ; temp1 mit ASCII '0'-1 vorladen lcd_number_2: inc temp ; ASCII erhöhen (somit ist nach dem ersten ; Durchlauf eine '0' in temp1) subi temp1, 10 ; 10 abziehen brcc lcd_number_2 ; ist dadurch kein Unterlauf enstanden? ; nein, dann zurück zu lcd_number_2 subi temp1, -10 ; 10 wieder dazuzählen, da die ; vorherhgehende Schleife 10 zuviel ; abgezogen hat /* push temp ldi temp,0x14 ; cursor nach rechts schieben rcall LCD_Senden pop temp*/ rcall LCD_DATEN ; die Zehnerstelle ausgeben ;** Einer ** ldi temp, '0' ; die Zahl in temp ist jetzt im Bereich add temp, temp1 ; 0 bis 9. Einfach nur den ASCII Code für rcall LCD_DATEN ; '0' dazu addieren und wir erhalten dierekt ; den ASCII Code für die Ziffer pop temp1 ; den gesicherten Inhalt von temp und temp1 pop temp ; wieder herstellen ret ; und zurück ;**************************************************************************************** ; 80*255*1/4000000 = ca 5 m_sec delay_5m: ;Wartezeit für längere Ausführzeiten (siehe Datenblatt) (CPU_FREQ beachten) push temp push temp1 ldi temp, 80 ; 80 mal warten_5m: ldi temp1, 255 ; 255 mal warten1_5m: dec temp1 ; 255-- brne warten1_5m ; temp2 = 0 dec temp ; 80-- brne warten_5m pop temp1 pop temp ret ;**************************************************************************************** ; 2*255*1/4000000 = ca 120 u_sec delay_100u: ;Wartezeit für kurze Ausführzeiten (siehe Datenblatt) (CPU_FREQ beachten) push temp push temp1 ldi temp, 2 ; 2 mal warten_100u: ldi temp1, 255 ; 255 mal warten1_100u: dec temp1 ; temp1 dekrementieren brne warten1_100u ; temp1 = 0 dec temp ; temp dekrementieren brne warten_100u pop temp1 pop temp ret ;**************************************************************************************** ; 1.Zeile des LCDs lcd_zeile1: push temp ldi temp, $80 ; LCD Adresse der 1.Zeile laden rcall LCD_Senden pop temp ret ; in die 2.Zeile des LCDs lcd_zeile2: push temp ldi temp, $c0 ; LCD Adresse der 2.Zeile laden rcall LCD_Senden pop temp ret