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.