Hi @all,
ich habe eigendlich folgendes Problem ich habe zum allerersten mal
Kontakt mit MC´s und habe mir von rowald.de das Testboard gebaut und
mir ein LCD Display gekauft, ok text habe ich schon hinbekommen. Jetzt
hab ich mal Probiert eine Tastenabfrage mit einzubauen.
Sprich:
Taste 1 lässt den Text einblenden
Taste 2 Bildschirm Löschen.
Schalte ich den MC an Funktioniert Taste 1 ok dann Taste 2...
aber leide bekomme ich nach dem LCD-Clearen keinen Text mehr wenn ich
dir Taste 1 Drücke... :( ich finde den Fehler einfach nicht...
Nun möchte ich euch in dieser Community mal bitten meinen Source
anzuschauen, und mir evtl. tips geben worauf ich achten sollte und
evtl. wo ich Grundlegende fehler gemacht habe, nicht das ich mir beim
lernen gleich gravierende Fehler aneigne.
Gruß Dennis
Source:
-----------------------------------------------------------------
.include "m8def.inc"
init:
ldi r21, HIGH(ramend) ; Stackpointer Init
out sph, r21
ldi r21, LOW(ramend)
out spl, r21
ldi zh, HIGH(text*2) ; Z-Pointer init
ldi zl, low(text*2)
ldi r16, 0b00011100 ; PD2,3,4 Ausgang
out ddrd, r16
ldi r16, 0b00001111 ; PC0,1,2,3 Ausgang
out ddrc, r16
ldi r16, 0b11010000
out portd, r16 ; Setze PD4 auf HIGH
main:
rcall lcd_init ; LCD-Initalisieren
rcall lcd_clear ; LCD-Clearen
loop:
sbis pind, 6
rcall print
sbis pind, 7
rcall lcd_clear
rjmp loop ; Dauer schleife
print: lpm ; Daten aus FlashROM lesen (Z-Pointer)
tst R0 ; Teste ob 0
breq print_end ; Wenn TEST = Wahr dann zu ...
mov r16, r0 ; Kopiere Inhalt von R0 (lpm) in r16
rcall lcd_data ; Gebe r16 auf LCD aus
adiw ZL,1 ; Erhöhe Z-Pointer Startpunkt um 1
rcall delay1s ; Pause
rcall delay1s ; Pause
rjmp print ; Und wieder von vorne
print_end:
ret ; Springe in die Endlosschleife
lcd_init:
ldi r18,50 ; 50x delay 5ms
powerupwait:
rcall delay5ms ; Pause von 5ms
dec r18 ; Decrement r18 -1
brne powerupwait ; und das so lange bis r18 = 0
ldi r16, 0b00000011 ; Init vom LCD (Siehe Datenblatt)
out PORTC, r16 ; PORTC Setzen
rcall lcd_enable ; LCD Enable
rcall delay5ms ; Pause 5ms
rcall lcd_enable ; LCD Enable
rcall delay5ms ; Pause 5ms
rcall lcd_enable ; LCD Enable
rcall delay5ms ; Pause 5ms
ldi r16, 0b00000010 ; LCD 4bit-Modus einstellen (Siehe
Datenblatt)
out PORTC, r16 ; PORTC Setzen
rcall lcd_enable ; LCD Enable
rcall delay5ms ; Pause 5ms
ldi r16, 0b00101000 ;noch was einstellen...
rcall lcd_command
ldi r16, 0b00001111 ;...nochwas...
rcall lcd_command
ldi r16, 0b00000100 ;endlich fertig
rcall lcd_command
ret
lcd_data:
sbi portd, 2 ; LCD Modus auf Daten
mov r17, r16 ; Kopiere r16 in r17
swap r16 ; Tausche
andi r16, 0b00001111
out PORTC, r16
rcall lcd_enable
andi r17, 0b00001111
out PORTC, r17
rcall lcd_enable
rcall delay50us
cbi portd, 2
ret
lcd_command: ;wie lcd_data, nur ohne RS zu
setzen
mov r17, r16
swap r16
andi r16, 0b00001111
out PORTC, r16
rcall lcd_enable
andi r17, 0b00001111
out PORTC, r17
rcall lcd_enable
rcall delay50us
ret
lcd_clear:
ldi r16, 0b00000001 ;Display löschen
rcall lcd_command
rcall delay5ms
ret
lcd_enable:
sbi PORTD, 4
nop
nop
nop
cbi PORTD, 4
ret
delay50us: ;50us Pause
ldi r16, $42
delay50us_:dec r16
brne delay50us_
ret
delay5ms: ;5ms Pause
ldi r16, $21
WGLOOP0: ldi r17, $C9
WGLOOP1: dec r17
brne WGLOOP1
dec r16
brne WGLOOP0
ret ;wieder zurück
delay1s: ;5ms Pause
ldi r16, $ff
delay1s1: ldi r17, $ff
delay1s2: dec r17
brne delay1s2
dec r16
brne delay1s1
ret ;wieder zurück
text:
.db "a",0
Das Programm sieht ja schon mal nicht schlecht aus. In der print - routine wird allerdings das Z-Register verändert, deshalb mußt Du das wieder auf den Anfang des Strings setzen, wenn Du den nochmal ausgeben möchtest! Viele Grüße Johannes
Und noch etwas: in der print - Routine erhöhst Du ZL immer um eines. Was aber, wenn der String zufällig über das Ende des "segments" hinausgeht (z.b. 0x01fa bis 0x0201)? Du solltest also das ganze Z-Registerpaar um 1 erhöhen, dafür gibt's einen eigenen Befehl. Ich habe hier auch schonmal meine eigene print_disp routine veröffentlicht, kannste über die Suchfunktion finden. cheeorio Johannes
Patsch.... da hab ich gar nicht drauf geachtet... Danke Dir ;) Vieleicht kannst Du mir noch helfen, bevor ich groß suche Habe noch folgende fragen: - Wie spreche ich in form von z.b. print routine die 2. Zeile an ? - Wie kann man Text in Form einer Laufschrift abarbeiten lassen... right in left out z.b. --------------------------------------------------------------------- >print: lpm ; Daten aus FlashROM lesen (Z-Pointer) > tst R0 ; Teste ob 0 > breq print_end ; Wenn TEST = Wahr dann zu ... > mov r16, r0 ; Kopiere Inhalt von R0 (lpm) in r16 > rcall lcd_data ; Gebe r16 auf LCD aus > adiw ZL,1 ; Erhöhe Z-Pointer Startpunkt um 1 * rcall delay1s ; Pause * rcall delay1s ; Pause > rjmp print ; Und wieder von vorne >print_end: > ret ; Springe in die Endlosschleife --------------------------------------------------------------------- Gibt es evtl. noch eine bessere möglichkeit, den Text delayed auszugeben, anstatt gleich eine übergroße delay schleife ? Gruß Dennis
keine Ahnung, wie es in Bascom geht, mit CV kann mn die Cursorposition, also die aktuelle Schreibmarke mit lcd_gotoxy(x,y); setzen. Was ähnliches müsste es auch in Bascom geben.
Die 2.Zeile beginnt an einer Speicheradresse, deren Wert im Datenblatt des Displays steht. Wenn Du die erste Zeile vollschreibst, kommst Du also irgendwan in einer anderen Zeile heraus (z.B. der zweiten bei einem zweizeiligen Display). Üblicherweise benutzt man den Befehl set_DDRAM_address, um den Cursor zu positionieren (mit lcd_command). Laufschrift, hm. Bei kurzen Texten in den Speicherbereich hinter den angezeigten Zeichen schreiben und die Display_shift commands (Datenblatt) benutzen. Bei sehr langen Strings ist sicherlich ein bißchen mehr Arbeit nötig, da kann ich Dir aus dem Stehgreif auch nichts sagen. Eine andere Möglichkeit für delays sind die Timer, mit denen ich allerdings noch nicht gearbeitet habe. Hier im Tutorial und in der Codesammlung gibt's aber Beispiele und Erklärungen dazu. Viele Grüße Johannes
@Johannes: Danke Dir trotzdem, habe jetzt meinen ADIW ZL,1 auf ADIW ZH:ZL,1 erweitert -> funktioniert das das Z-Registerbetrifft überlege ich grad wie ich diesen zurücksetze... :( evtl. PUSH ZH:ZL und am ENDE POP ZH:ZL ? @Crazy: Wie kommst Du auf Bascom ? ist doch alles ASM ! ;) Habe mich genau 10 Minuten mit Bascom beschäftigt... 5 Min zum Installieren 2 Min zum Test und dann 3 Min zum deinstallieren... lol Erzeugt mir einfach einen zu großen Code im AVR um genau das gleiche in Bascom zu machen wie diesen einfach string mit Tastensteuerung auszugeben benötige ich in Bascom schon fast 450 blöcke... ASM bin ich bei 105... Muss ja nicht gleich den AVR zuhauen... wer weis, wann ich die routinen noch mal brauche ;) Gruß @all von Dennis P.S.: ist ein Super Forum hier sehr schnelle Antworten, SUPER TEAM ;) Auch wenn ich PHPbb vorziehe als Board... ;)
stimmt - nimms als black out nach einer langen Nacht :-)
Kannst doch einfach ldi zh, HIGH(text*2) ; Z-Pointer init ldi zl, low(text*2) mit in die Schleife schreiben, muß ja zum Testen nicht elegant sein... Die ZH und ZL müßte man schätzungsweise getrennt pushen bzw. "poppen".
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.