Darüberhinaus besteht die Möglichkeit, eigene Zeichen zu definieren und anzuzeigen. Hier soll gezeigt werden, wie man dieses mit einem Assembler Programm machen kann. Prinzipiell geht das mit jedem Mikrocontroller, die hier verwendete Termnologie orientiert sich an Atmel AVR Prozessoren. Dabei wird vorausgesetzt, dass der Leser mit der Grundsätzlichen Ansteuerung eines HD44780 kompatiblen Displays vertraut ist und die prinzipielle Übergabe von Befehlen und Daten an das Display verstanden wurden.
Zuerst müssen wir uns ansehen, wie so ein Zeichen überhaupt aufgebaut ist. Prinzipiell besteht es immer aus 8 Bytes, deren einzelne Bits das Muster der anzuzeigenden Pixel definieren Hier als Beispiel mal ein A, welches auf dem Kopf steht: 00010001 -> Erste Zeile00010001
00011111
00010001
00001010
00001010
00000100
00000000 -> Letzte Zeile
Dabei einspricht jedes 1-Bit einem schwarzen Pixel auf dem Display, jedes 0 Bit bedeutet ein nicht gesetztes Pixel. Für jedes Zeichen, für jede Ziffer und für jedes Sonderzeichen gibt es im internen Zeichen-Rom also einen 8 Bytes Block, in welchem eine entsprechende Pixeldarstelliung hinterlegt ist. Soll nun ein Zeichen auf dem LCD Display angezeigt werden, holt sich der Controller die Informationen aus dem entsprechenden Character ROM Speicherbereich, und das Zeichen erscheint auf dem Display. Die meisten Zeichen sind, wie gesagt, in einem Read Only Memory abgelgt, man kann sie nicht verändern. Jedoch gibt es auch einen kleinen Speicherbereich im Zeichengenerator, den man beschreiben kann. Der HD44780 Controller hat für genau diesen Zweck 64 Bytes als beschreibbares Character RAM. Da ein Zeichen 8 Bytes benötigt, können also 8 benutzerdefinierte Zeichen mit 8*8 Pixel angelegt werden. Bei jedem Zechen sind davon aber nur 5*8 Bits sichtbar, die obersten 3 Bit werden einfach ignoriert. Um ein Zeichen zu definieren, müssen wir zuerst einmal festlegen, welches der 8 Zeichen wir definieren wollen. Die frei definierbaren Zeichen haben den Code 0 bis 7. Jedes Zeichen benötigt 8 Bytes im Speicher. Um also zm Beispiel das Zeichen Nummer 6 zu ändern, müssen wir also die Bytes ab der Speicheradresse 6*8=48 hinterlegen. Dazu wird der LCD Befehl set_cg_ram_address mit der Adresse 48 verknüpft und an das Display geschickt. Danach werden 8 Datenbytes hintereinander an das LCD geschickt, und schon kann das benutzerdefinierte Zeichen verwendet werden. In Hexadezimal-Schreibweise entsprechen die oben aufgelisteten Daten den Werten $00,$11,$11,$1f,$11,$0a,$0a,$04 Mit folgenden Befehlen kann diese Zeichendefinition dann an das LCD Display übermittelt werden:ldi temp1,$06
rcall set_cg_ram_address
ldi temp1,$00
rcall lcd_data
ldi temp1,$11
rcall lcd_data
ldi temp1,$11
rcall lcd_data
ldi temp1,$1f
rcall lcd_data
ldi temp1,$11
rcall lcd_data
ldi temp1,$0a
rcall lcd_data
ldi temp1,$0a
rcall lcd_data
ldi temp1,$04
rcall lcd_data
rcall lcd_home
....
Wichtig ist dabei in jedem Fall, dass nach dem Übertragen der Zeichendefinition das Display wieder so gesetzt werden muss, das die Zeichen ausgegeben werden, zum Beispiel durch lcd_home oder set_ddram_adress. Sonst gehen weitere Schreibzugriffe permanent in das Character RAM!