mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Menü für LCDs in Assembler


Autor: Stefan Friedrich (stefan1987)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ich bin gerade dabei eine Menüstruktur für mein LCD zu entwerfen.
Auf dem Bild sieht man welche Bildschirminhalte auf dem LCD dargestellt 
werden sollen, welche Funktionen die Taster haben sollen und wo Leds und 
LCD angeschlossen sind.
Ausserdem sieht man welche Werte die Register 4 und 5 haben sollen bei 
welchem Menübildschirm.

Meine erste Idee war mit CPI die Tasterwerte zu Vergleichen und dadurch 
die Bildschirminhalte zu wechseln. Allerdings wird das sehr viel Code.

Dann hatte ich noch eine Idee über Sprungtabellen, weiss aber nicht ob 
es das besser macht.

Ich habe öfters was über Arrays hier im Forum gelesen wenn es um Menüs 
ging, konnte allerdings nichts dazu finden wie man solche Arrays in 
Assembler definiert und diese benutzt. Geht das mit Assembler ?

Oder welches wäre die effizienteste Lösung für solch ein Problem ?

Ausserdem gibt es ja in den LCD routinen den Befehl einen String 
auszugeben.
Also die Sache mit .db text1 "............" ,0

gibts da eine Möglichkeit an dieser Stelle wo diese Strings dann 
ausgegeben werden
,also da wo die einzelnen texte in den Z-Pointer geladen werden zum 
beispiel eine Variable einzusetzen das man nicht für jeden Displayinhalt 
ein neues Unterprogram schreiben muss so wie diesses hier ?


          ldi ZL, LOW(text8*2)        ; Adresse des Strings in den
          ldi ZH, HIGH(text8*2)       ; Z-Pointer laden
          rcall lcd_flash_string_o    ; Unterprog. gibt String aus der
                                      ; durch Z-Pointer adres. wird

          ldi ZL, LOW(text9*2)        ; Adresse des Strings in den
          ldi ZH, HIGH(text9*2)       ; Z-Pointer laden
          rcall line2                 ; Zeile 2 im LCD oben
          rcall lcd_flash_string_o    ; Unterprog. gibt String aus der
                                      ; durch Z-Pointer adres. wird

          ldi ZL, LOW(text10*2)       ; Adresse des Strings in den
          ldi ZH, HIGH(text10*2)      ; Z-Pointer laden
          rcall lcd_flash_string_u    ; Unterprog. gibt String aus der
                                      ; durch Z-Pointer adres. wird

          ldi ZL, LOW(text11*2)       ; Adresse des Strings in den
          ldi ZH, HIGH(text11*2)      ; Z-Pointer laden
          rcall line4                 ; Zeile 4 im LCD unten
          rcall lcd_flash_string_u    ; Unterprog. gibt String aus der
                                      ; durch Z-Pointer adres. wird

          ret                         ; zurück




Vielen Dank schonmal

Grüße Stefan

Autor: Hannes Lux (hannes)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Schreib Dir eine Ausgaberoutine, die indizierte Texte ausgeben kann, 
also Texte, die über eine Sprungtabelle adressiert werden. Ein Beispiel 
ist im Anhang.

Der Aufruf erfolgt so:

printmenu:              ;Einsprung
 printt menutab,mp          ;neuen Menütext ausgeben

Die Texte sehen so aus:

menutab:
.dw mt0,mt1,mt2,mt3,mt4,mt5,mt6,mt7

mt0:    .db 4,"1-Abkuehlen    ",0,0
mt1:    .db 4,"2-Platinen     ",0,0
mt2:    .db 4,"3-Normalpapier ",0,0
mt3:    .db 4,"4-Fotopapier   ",0,0
mt4:    .db 4,"5-extra dick   ",0,0
mt5:    .db 4,"6-Reserve      ",0,0
mt6:    .db 4,"7-Reserve      ",0,0
mt7:    .db 4,"8-Reserve      ",0,0

Nur um die "4" zu erklären: Die LCD-Routine arbeitet mit 
Bildschirmspeicher im AVR-SRAM und unterstützt einige Steuerzeichen:

;----------------------------------------------------------------------
;  lcd_data       ;Übergibt das Byte (ASCII-Zeichen) im Register "tmp"
                  ;zur Textausgabe. Dabei sind folgende Steuerzeichen
                  ;möglich:
                  ;1:  Blinken ausschalten
                  ;2:  akt. Ausgabe-Position als Blinkanfang setzen
                  ;3:  akt. Ausgabe-Position als Blinkende setzen
                  ;4:  Bildschirm löschen
                  ;8:  Cursor home (ohne Löschen)
                  ;13: CR, Zeilenwechsel, Rest der Zeile wird gelöscht
;----------------------------------------------------------------------


...

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Da hast du dir was nettes vorgenommen. Wie gut bist du in Assembler?

>Meine erste Idee war mit CPI die Tasterwerte zu Vergleichen und dadurch
>die Bildschirminhalte zu wechseln. Allerdings wird das sehr viel Code.
>Dann hatte ich noch eine Idee über Sprungtabellen, weiss aber nicht ob
>es das besser macht.

Da würde ich Sprungtabellen vor ziehen.

>Ich habe öfters was über Arrays hier im Forum gelesen wenn es um Menüs
>ging, konnte allerdings nichts dazu finden wie man solche Arrays in
>Assembler definiert und diese benutzt. Geht das mit Assembler ?

abcd: .db 1,2,3,4,5,6,7,8

ist in Assembler das gleiche, wie in C ein Array. Allerdings werden für 
Menüs eher Arrays aus zusammengesetzten Datentypen (C:Struct, 
Pascal:record) verwendet. Geht aber in Assembler auch:

abcd:  .db 'asdefrgthzju'    ; Menütext
       .dw Tasten1           ; Tastaturhandler
       .dw verarb1           ; Verarbeitungsroutine
       ....

Wenn die Menütexte eine konstante Länge habe kannst du Offsets 
definieren um auf die einzelnen Werte zuzugreifen:

   .equ Text = 0
   .equ tasten = 14
   ....

Zugriff mit z.B.

   ldi ZL,low(abcd<<1)
   ldi,ZH,High(abcd<<1)

   adiw ZH:ZL,tasten

   lpm rxy,Z+
   lpm ZH,Z
   mov ZL,rxy
   icall          ; zugehörige Tastaturroutine aufrufen

Ich habe das nur mal angerissen. Es gibt nichts, was 'höhere' 
Programmiersprachen können, was mit Assembler nicht realisierbar ist.

MfG Spess



   ZL,X+tasten
   ldd ZH,

Autor: Stefan Friedrich (stefan1987)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

danke für die schnellen Antworten :)

@Hannes:

Also wenn ich das richtig verstehe fasst du die einzelnen Textzeilen mit 
.dw zu einem "Paket" zusammen ?
und in pr_txt.inc ist das printt macro für die ausgabe solcher "Pakete" 
auf das LCD zuständig ?
Was hat denn das @ im Quelltext zu bedeuten ?
" ldi tmp,low(@0*2)          ;Basisadresse"

Und das Unterprogramm lcd_printf1 ist der normale Ausgabebefehl für 
Strings auf dem LCD oder?

@spess53

> Wie gut bist du in Assembler?
Bin eher ein Assembler Anfänger. Arbeite das Tutorial hier durch.
Blinklichter, Lauflichter, Sprungtabelle, LCD Textausgabe, Tasterabruf 
usw versteh ich ganz gut. PWM vom Prinziep her auch.

> Wenn die Menütexte eine konstante Länge habe kannst du Offsets
> definieren um auf die einzelnen Werte zuzugreifen:
Ja die Texte hab ich alle gleichlang gemacht und in menues.asm 
definiert.
Ich kann sie auch einzeln ohne Probleme auf dem LCD ausgeben.
Bin grad auf der Suche nach einer Lösung wie ich indizierte Texte ausgeb 
so wie Hannes das oben beschrieben hat, bzw versuch es zu verstehn. :)


danke nochmal :)

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
HI

>Was hat denn das @ im Quelltext zu bedeuten ?
>" ldi tmp,low(@0*2)          ;Basisadresse"

Der Quelltext gehört zu einem Macro.

Dem Makroaufruf:
  printt Adresse, Index

werden zwei Parameter übergeben: Adresse -> @0
und                              Index   -> @1

ldi tmp,low(@0*2) wird zu ldi tmp,low(Adresse*2) erweitert.

MfG Spess

Autor: Sepp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vorsicht bei der Definition mit ".dw", wegen der Reihenfolge
der Ablage der Werte. Bei .dw kommt das niederwertige Byte zuerst!

Bei Texten nimmst Du .db  "Dies ist ein Text",0x00
Ggf.noch eine Null am Textende weil es immer eine gerade Anzahl an 
Zeichen
geben muß, der Assembler mault aber wenn es nicht paßt.

Dann kannst Du mit einer einfachen Ausgaberoutine den Text ausgeben,
Textende/ausgabeende ist die Null.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>der Assembler mault aber wenn es nicht paßt.

Der mault nicht nur, sondern er tut auch etwas. Nämlich das fehlende 
Byte zu ergänzen.

MfG Spess

Autor: Hannes Lux (hannes)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Friedrich schrieb:
> Hallo,
>
> danke für die schnellen Antworten :)
>
> @Hannes:
>
> Also wenn ich das richtig verstehe fasst du die einzelnen Textzeilen mit
> .dw zu einem "Paket" zusammen ?

Paket würde ich das nicht nennen, es sind einfach nur die Adressen, an 
denen die Texte beginnen. Natürlich nicht im Klartext (als Zahlenwert), 
sondern als Label. Somit kann der Assembler beim Assemblieren anstelle 
der Labels die Adressen einsetzen.

> und in pr_txt.inc ist das printt macro für die ausgabe solcher "Pakete"
> auf das LCD zuständig ?

Das Macro ist dafür zuständig, eine Routine aufzurufen, die den 
Z-Pointer auf die Adresse (mal 2, wegen LPM) des Textes positioniert und 
dann die Routine aufruft, die den Text an das LCD ausgibt.

> Was hat denn das @ im Quelltext zu bedeuten ?
> " ldi tmp,low(@0*2)          ;Basisadresse"

Damit werden die Parameter des Macros markiert. @0 ist der erste 
Parameter, @1 der zweite, aber das hat Spess ja schon erklärt.

>
> Und das Unterprogramm lcd_printf1 ist der normale Ausgabebefehl für
> Strings auf dem LCD oder?

Jaein...
lcd_printf (Print aus Flash) ist die normale Ausgaberoutine für Strings, 
die mit $0 beendet werden. Sie wird vom Macro printf aufgerufen.
Im Fall von indizierten Texten positioniert aber die Routine lcd_printt 
bereits den Z-Pointer, daher wird lcd_printf hinter der 
Pointer-Positionierung angesprungen, also bei lcd_printf1.

Da vor ".dw" gewarnt wurde:
Texte notiert man mit ".db", denn es handelt sich um Datenbytes. Die 
Adressen der Labels sind aber 16-Bit-Worte. Um sie korrekt als 
16-Bit-Zahl notieren zu können, müssen jeweils 2 Bytes (ein Word) dafür 
im Flash reserviert werden. Und genau dies macht ".dw". Siehe dazu auch 
den Hilfetext zu den Direktiven im AVR-Studio.

Um Dir das Analysieren der Routinen zu erleichtern, hänge ich mal das 
gesamte Programm an.

...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.