mkprojekt.de

Nachdem ich im ersten Teil ein paar Grundlagen der Displayansteuerung beschrieben habe, gehe ich in diesem Teil ein wenig weiter und erläutere, wie man einen kompleten String ausgeben kann (quasi ein Äquivalent zu der "print"-Methode für die HD4488-Controller).', '

Erst einmal muss man sich eine kleine Prozedur schreiben, mit der man den Datenzeiger des Displays positionieren kann. Hierzu springt man (im Kommando-Mode) an die passende Speicherstelle. Das Display hat 6 Speicherbänke mit jeweils 84 Bytes. Hieraus ergibt sich die physikalische Auflösung von (8 Bit = 1 Byte => 6 * 8 = 48) 48 * 84 Pixel. Da der im ersten Teil "entworfene" Zeichensatz pro Zeichen 6 Bytes hat, ist es sinnvoll die 84 Bytes in 14 Abschnitte zu je 6 Bytes zusammen zufassen.
Nun kann man eine Funktion schreiben, mit der man unter Angabe von zwei Variablen sich "frei" auf dem Display bewegen kann.

 

Sub position(Byval X As Byte , Byval Y As Byte)          // Y sind die Zeilen (0-5), X entsprechend die Zeichen (0-13)
        Local Nout As Byte
        Dc = 0                          // in den Kommandomode
        Ce = 0
        Nout = Y + 64        
        Spiout Nout , 1
        Ce = 1
        Ce = 0
        Nout = X * 6
        Nout = Nout + 128
        Spiout Nout , 1
        Ce = 1
        Dc = 1
    End Sub

 

Aufmerksame Leser werden sich jetzt vielleicht fragen, wieso vor dem schreiben der Displayposition auf der SPI-Schnittstelle noch eine 64 bei der y-Koordinate und eine 128 bei der x-Koordinate aufaddiert werden.
Damit  der Display-Controller überhaupt weiß, welche der beiden Koordinaten überhaupt übertragen werden, muss dies mittels eines Bits angegeben werden. Wenn das MSB (also das ganz linke Bit eines Bytes mit der Wertigkeit "128" in Dezimalzahl) gesetzt ist, dann wird die x-Koordinate gesetzt. Bei der 64 ist es das zweite von links, also das 6. (das ganz rechte, LSB, ist das "0-te") mit der Wertigkeit 64. Wenn man das jetzt mal in Binärzahlen schreibt sieht das so aus:

x-Koordinate: 1xxx  xxxx
y-Koordinate: 0100 0yyy

wobei hier die x für die entsprechende Binärzahl von 0-83 und die y für die Binärzahl von 0-5 stehen. 

Da, wie oben beschrieben, unser Zeichensatz eine Breite von 6 Pixel hat, wird die x-Adresse zusätzlich mit 6 multipiziert.

 

Nachdem wir den Adresspointer im Display setzten können, brauchen wir eine Funktion Nprint, die eine Zeichenkette von maximal 14 Zeichen in einzelne Zeichen zerlegt, die entsprechende Stelle im internen Speicher sucht, und dann byteweise an das Display schickt. Da dies meiner Meinung nach in einer Funktion ein wenig zu unübersichtlich wird, habe ich diese beiden Funktionen getrennt. Einmal Nprint, die die Zeichenkette "auseinandernimmt" und die Stelle im Speicher sucht, und einmal eine Funktion Zeichenout, die immer ein Zeichen (6 Byte) an das Display sendet.

 

Sub Nprint(Byval Text As String * 14)
        Local Loops As Byte
       
Local Laenge As Byte
        Local Zeichen As String * 1
        Laenge = Len(Text)                        // Feststellen der Länge von Text
        For Loops = 1 To Laenge                // Für jedes Zeichen wird die Schleife einmal durchlaufen...
            If Loops = 1 Then                       // ...und jeweils in die lokale Variable Zeichen gespeichert
               Zeichen = Left(Text , 1)
            Elseif Loops = Zeichen Then
               Zeichen = Right(Text , 1)
            Else
               Zeichen = Mid(Text , Loops , 1)
            End If
            If Zeichen = "0" Then Restore 0:   // hier wird der Datenpointer im AVR gesetzt.
            If Zeichen = "1" Then Restore 1:
            .....                                            // immer so weiter...
            Call Zeichenout                           // Aufruf von Zeichenout, um das Zeichen zu schreiben
        Next Loops
    End Sub

 

Der Funktion Nprint wird ein String von maximal 14 Zeichen übergeben, die Länge festgestellt und dann Zeichenweise behandelt. Die Zeichen mittels If-Abfrage zu lokalisieren, ist nicht gerade die eleganteste Methode, jedoch ist sie sehr einfach zu verstehen. Alternativ könnte man auch einen ganzen Datenblock im Speicher ablegen und über den ASCII-Code eines Zeichens einen kleinen Algorithmus schreiben, der die zugehörige Speicherstelle findet.
Mit Restore setzt man den Datenpointer im AVR auf die gewünschte Stelle. Man kann nun mit Read auf diese Daten zugreifen.
In unserem Fall legt man den Zeichensatz folgendermaßen ab:

 

    0:
    Data &H00 , &H3E , &H51 , &H49 , &H45 , &H3E
    1:
    Data &H00 , &H00 , &H42 , &H7F , &H40 , &H00
    2:
    Data &H00 , &H42 , &H61 , &H51 , &H49 , &H46
    ....                                                   // und so weiter

 

Hier jetzt die Funktion Zeichenout:

 

Sub Zeichenout
        Local Count As Byte
        Local
Daten As Byte
        Dc = 1                                        //in den Datenmode
        For Count = 1 To 6
            Read Daten
            Ce = 0
            Spiout Daten , 1
            Ce = 1
        Next Count
        Dc = 0
    End Sub

 

Mit Read schreiben wir das erste Byte von der Stelle, an der sich der Datenpointer im Moment befindet in die Variable Daten. Über Spiout geben wir das Byte nun über den SPI-Port aus (siehe Teil 1). Da wir pro Zeichen sechs Byte haben, müssen wir das ganze mit einer For-Schleife wiederholen.
Nun können wir Text an einer (fast) beliebigen Stelle am Display ausgeben. Hierzu müssen wir nur die Funktion "posisiton" mit den entsprechenden Werten aufrufen und hinterher die Funktion "Nprint" mit dem auszugebenden Text.