.include "m8def.inc"
;PD7----->DB7
;PD6----->DB6
;PD5----->DB5
;PD4----->DB4
;PD3----->Enable ;Bei Fallender Flanke liest der LCD die Daten
;PD2----->RS 0=Kommando senden 1=Daten senden
;GND----->R/W 0=Daten an LCD-senden
.equ lcd = portd
.equ enable = 8
.equ rs = 4
rjmp init
init:
;Stackpointer initialisieren
ldi r16,high(ramend)
out sph,r16
ldi r16,low(ramend)
out spl,r16
;PD2-PD7 als ausgang Schalten
ldi r16,0b11111100
out ddrd,r16
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;LCD initialisieren
initLCD:
rcall wait
ldi r16,0b00100000 ;4bitmodus einschalten
rcall command ;Befehl Senden
ldi r16,0b00101000 ;4bitmodus,2Zeiliges Display, 5X7 Font
rcall befehl ;Byte in High and low nibble teilen und senden
ldi r16,0b00001100 ;Display ein
rcall befehl ;Byte in High and low nibble teilen und senden
ldi r16,0b00000110 ;Automatisches Inkrementieren des Cursors Aktivieren
rcall befehl ;Byte in High and low nibble teilen und senden
clear:
ldi r16,0b00000001 ;Display löschen und Cursor auf Anfangsposition setzen
rcall befehl ;Byte in High and low nibble teilen und senden
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Text Ausgeben
main:
ldi r16,'H'
rcall text
ldi r16,'A'
rcall text
ldi r16,'L'
rcall text
ldi r16,'L'
rcall text
ldi r16,'O'
rcall text
ldi r16,' '
rcall text
ldi r16,'F'
rcall text
ldi r16,'O'
rcall text
ldi r16,'R'
rcall text
ldi r16,'U'
rcall text
ldi r16,'M'
rcall text
ldi r16,' '
rcall text
rcall wait1
rjmp clear
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Verzögerung für garantierten Pegel am Dataport des LCD
wait:
ldi xh,high(1500)
ldi xl,low(1500)
rjmp loop
;Verzögerung am Ende des Schriftzuges
wait1:
ldi xh,high(60000)
ldi xl,low(60000)
rjmp loop
;Warteschleife
loop:
sbiw xl,1
brne loop
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Setzt RS auf High , gesendetes Byte wird auf dem Display ausgegeben
data:
sbr r16,rs
rjmp send
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Loescht RS , gesendetes Byte ist ein Befehl
command:
cbr r16,rs
rjmp send
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
send:
sbr r16,enable ;Enable auf High seten
out lcd,r16
rcall wait
cbr r16,enable ;Enable auf low setzeb ;Daten werden übertragen
out lcd,r16
rcall wait
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Byte in High und Low Nibble aufteilen und senden
Befehl:
mov r17,r16 ;sichere r16 nach r17
andi r16,0b11110000 ;low nibble auf low setzen
rcall command ;Befehl Senden
mov r16,r17 ;Ursprünglichen Befehl aus r17 nach r16 laden
swap r16 ;High and low nibble Tauschen
andi r16,0b11110000 ;low nibble auf low setzen
rcall command ;Befehl Senden
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Byte in High und Low Nibble aufteilen und senden
text:
mov r17,r16 ;sichere r16 nach r17
andi r16,0b11110000 ;low nibble auf low setzen
rcall data ;Befehl Senden
mov r16,r17 ;Ursprünglichen Befehl aus r17 nach r16 laden
swap r16 ;High and low nibble Tauschen
andi r16,0b11110000 ;low nibble auf low setzen
rcall data ;Befehl Senden
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
So wen es interressiert hier die 4bit Initialisierung meines Displays
Code:.include "m8def.inc" ;PD7----->DB7 ;PD6----->DB6 ;PD5----->DB5 ;PD4----->DB4 ;PD3----->Enable ;Bei Fallender Flanke liest der LCD die Daten ;PD2----->RS 0=Kommando senden 1=Daten senden ;GND----->R/W 0=Daten an LCD-senden .equ lcd = portd .equ enable = 8 .equ rs = 4 rjmp init init: ;Stackpointer initialisieren ldi r16,high(ramend) out sph,r16 ldi r16,low(ramend) out spl,r16 ;PD2-PD7 als ausgang Schalten ldi r16,0b11111100 out ddrd,r16 ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;LCD initialisieren initLCD: rcall wait ldi r16,0b00100000 ;4bitmodus einschalten rcall command ;Befehl Senden ldi r16,0b00101000 ;4bitmodus,2Zeiliges Display, 5X7 Font rcall befehl ;Byte in High and low nibble teilen und senden ldi r16,0b00001100 ;Display ein rcall befehl ;Byte in High and low nibble teilen und senden ldi r16,0b00000110 ;Automatisches Inkrementieren des Cursors Aktivieren rcall befehl ;Byte in High and low nibble teilen und senden clear: ldi r16,0b00000001 ;Display löschen und Cursor auf Anfangsposition setzen rcall befehl ;Byte in High and low nibble teilen und senden ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;Text Ausgeben main: ldi r16,'H' rcall text ldi r16,'A' rcall text ldi r16,'L' rcall text ldi r16,'L' rcall text ldi r16,'O' rcall text ldi r16,' ' rcall text ldi r16,'F' rcall text ldi r16,'O' rcall text ldi r16,'R' rcall text ldi r16,'U' rcall text ldi r16,'M' rcall text ldi r16,' ' rcall text rcall wait1 rjmp clear ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;Verzögerung für garantierten Pegel am Dataport des LCD wait: ldi xh,high(1500) ldi xl,low(1500) rjmp loop ;Verzögerung am Ende des Schriftzuges wait1: ldi xh,high(60000) ldi xl,low(60000) rjmp loop ;Warteschleife loop: sbiw xl,1 brne loop ret ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;Setzt RS auf High , gesendetes Byte wird auf dem Display ausgegeben data: sbr r16,rs rjmp send ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;Loescht RS , gesendetes Byte ist ein Befehl command: cbr r16,rs rjmp send ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ send: sbr r16,enable ;Enable auf High seten out lcd,r16 rcall wait cbr r16,enable ;Enable auf low setzeb ;Daten werden übertragen out lcd,r16 rcall wait ret ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;Byte in High und Low Nibble aufteilen und senden Befehl: mov r17,r16 ;sichere r16 nach r17 andi r16,0b11110000 ;low nibble auf low setzen rcall command ;Befehl Senden mov r16,r17 ;Ursprünglichen Befehl aus r17 nach r16 laden swap r16 ;High and low nibble Tauschen andi r16,0b11110000 ;low nibble auf low setzen rcall command ;Befehl Senden ret ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;Byte in High und Low Nibble aufteilen und senden text: mov r17,r16 ;sichere r16 nach r17 andi r16,0b11110000 ;low nibble auf low setzen rcall data ;Befehl Senden mov r16,r17 ;Ursprünglichen Befehl aus r17 nach r16 laden swap r16 ;High and low nibble Tauschen andi r16,0b11110000 ;low nibble auf low setzen rcall data ;Befehl Senden ret ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sehr ordentlich und sauber strukturiert und kommentiert.
Irgendwie wird mir bei den vielen "unnützen" Wartetakten (mehr als 4*1500 bzw 4*60000) immer ganz komisch... wir Menschen sind ja sooooo langsam...
Hinter Deinem command-label springst Du zum send-label (welches direkt dahinter kommt), Dieser Sprung ist unnötig, Du hast ihn trotzdem der Übersichtlichkeit halber drin, ist mir klar. So kann man weniger falsch machen, falls da noch was eingefügt wird, klar.
...und interessieren tut das immer