Forum: Mikrocontroller und Digitale Elektronik Routine für Zeichen Definition, HD44780, CGRAM, 2x16 Displa


von Bernhard Bauer (Gast)


Lesenswert?

Hallo,

hat hier vielleicht jemand eine gut funktionierene Routine, mit der man
auf einem 2x16 Display im CGRAM freie Zeichen definieren kann.
Ich habe selbst eine Routine geschrieben, die allderings nicht zu
funktionieren scheint:




.
.
.
DEFINE_CHAR:  ldi temp1, 0b01000000  ;Setze CGRAM Adresse auf 0
rcall LCD_COMMAND       ;Befehl Ausführen (RS=0)
    ldi ZL, LOW(2*char1)    ;Z_Pointer laden
    ldi ZH, HIGH(2*char1)
    rcall PRINT

PRINT:    lpm                     ;Z-Pointer Inhalt nach R0
    tst r0                  ;Teste R0 auf 0 (Abschluss)
    breq PRINT_END
    mov temp1, r0
    rcall LCD_DATA          ;Daten aufs LCD (RS=1)
    adiw ZL, 1
    rjmp PRINT
PRINT_END:  ret

char1:          .db 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0
.
.
.
.


Die Funktionen LCD_COMMAND und LCD_DATA funktionieren sicher. Ich habe
sie schon anderweitig getestet.
Vielleicht hat jemand eine elegantere und vor allem funktionierende
Lösung hierzu.

DesWeiteren habe ich folgende Frage: Ist es überhaupt sinnvoll auf die
CGRAM Adresse 0 ein Zeichen zu definieren, da dieses Zeichen dann den
ASCII-Code 0 hat und gleichzeitig auch als Abschluss eines Strings
hergenommen wird, und somit nie geschrieben wird.
Ein Simulationsprogramm für 2x16 LCD mit HD44780 Controller findet man
unter:
http://www.sxlist.com/techref/io/lcd/djlcdsim/djlcdsim.html
Dort funktioniert meine Routine, nur in der Realität nicht.
Für Lösungsansätze wäre ich sehr dankbar.

Gruß
Bernhard

von crazy horse (Gast)


Lesenswert?

DEFINE_CHAR:  ldi temp1, 0b01000000  ;Setze CGRAM Adresse auf 0

rcall LCD_COMMAND       ;Befehl Ausführen (RS=0)
    ldi ZL, LOW(2*char1)    ;Z_Pointer laden
    ldi ZH, HIGH(2*char1)
    rcall PRINT
hier fehlt ein ret, wie soll es denn weiter gehen, wenn das Programm
von print zurückkommt?

PRINT:    lpm                     ;Z-Pointer Inhalt nach R0
    tst r0                  ;Teste R0 auf 0 (Abschluss)
    breq PRINT_END
    mov temp1, r0
    rcall LCD_DATA          ;Daten aufs LCD (RS=1)
    adiw ZL, 1
    rjmp PRINT
PRINT_END:  ret


char1:          .db 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0

Ob das mit tst 0 der richtige Weg ist? Kann ja schon mal vorkommen,
dass in einem Zeichen eine 0 vorkommt. Eine einfache for/next
-schleife mit fester Schleifenzahl entsprechend der Spaltenzahl (oder
wird das zeilenweise adressiert? Weiss ich jetzt nicht aus dem Kopf.)
des Displays.

von Hannes L. (hannes)


Lesenswert?

Eine Routine habe ich nicht, da ich bisher immer mit dem vorhandenen
ROM-Zeichensatz zurecht kam.

Was Adresse 0 betrifft, die 8 selbstdefinierten Zeichen sind doch auch
über Adresse 8...15 erreichbar.

...

von Lightning (Gast)


Lesenswert?

Hy,
Ich hab eine die mit dem LCD-Code
aus dem AVR-Tutorial funktioniert:

.......
.......
.......


           rcall lcd_init
           rcall lcd_clear    ;Display löschen

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;In den CG-RAM wechseln (Addresse 0)
ldi temp1, 0x48
rcall lcd_command
;----------------------------------------------------
;Daten senden (Zeichen deffinieren) (Die ersten 3 Bit's müssen 0 sein
da nur 5 Pixel/Zeile)
ldi temp1, 0b00010001 ;#ooo#
rcall lcd_data

ldi temp1, 0b00001010 ;o#o#o
rcall lcd_data

ldi temp1, 0b00000100 ;oo#oo
rcall lcd_data

ldi temp1, 0b00001010 ;o#o#o
rcall lcd_data

ldi temp1, 0b00000100 ;oo#oo
rcall lcd_data

ldi temp1, 0b00001010 ;o#o#o
rcall lcd_data

ldi temp1, 0b00010001 ;#ooo#
rcall lcd_data


;Cursorzeile sollte leer
;bleiben, kann aber auch Deffiniert werden:

ldi temp1, 0b00000000 ;ooooo
rcall lcd_data
;----------------------------------------------------

;Wieder in den DD-RAM wechseln
ldi temp1, 0b10000000
rcall lcd_command
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

;deffiniertes Zeichen aufrufen.
ldi temp1, 0x01
       rcall lcd_data

loop:
rjmp loop  ;Endlosschleife


.......
.......
.......

Gruß Lightning

von Bernhard Bauer (Gast)


Lesenswert?

Vielen Dank für die Tipps. Manchmal sieht man halt den Wald vor lauter
Bäumen nicht mehr. Nun aber noch eine Frage:

Wenn ich in den CGRAM wechsle (z.B. Adresse 0), dann wechselt der
Cursor in die zweite Zeile, erste Spalte, bei Adresse 1 dann in die
zweite Spalte. Ich möchte ja eigentlich im CGRAM Zeichen definieren,
und nicht die Cursor-Position wechseln. Ist das normal, oder gewollt?
Wenn ja für welche Zwecke, oder muß man darüber hinweg sehen?
Danke schon mal für die Antworten.

Gruß
Bernhard

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
Noch kein Account? Hier anmelden.