Die Anzeige erfolgt mit 8 Stück rot leuchtenden LED-Punktmatrixanzeigen vom Typ VQC10 aus DDR-Produktion. Also schon etwas älter, aber sie sehen immer noch verdammt gut aus. Erhältlich ist so etwas höchstens noch auf Flohmärkten oder Restbeständen. Jede Anzeige hat 4 Stellen mit 5 * 7 Leuchtdioden. Insgesamt sind also 1120 Leuchtdioden zu steuern. Die Spaltenansteuerung wird intern gespeichert, während die Zeilen nichtspeichernd über Transistoren gegen +5 Volt geschaltet sind.
Zuerst werden die Ports für die Ansteuerung der Anzeige als Ausgänge deklariert. Die etwas ungewöhnliche Aufteilung der Ports beruht darauf, das der auf der Originalleiterplatte gesockelte Prozessor durch den AVR ersetzt wurde. Die Portbelegung war dort natürlich vollkommen inkompatibel, aber es sollten soviel wie möglich Leiterzüge weiter verwendet werden. Dann benötigen wir ein je Byte für die Anzeigestelle, die Zeilennummer und ein Array für die Spalten (Daten). Diverse Variablen werden für die Steuerung der Helligkeit benötigt. Der 16-bit-Timer misst die Laufzeit eines kompletten Programmdurchlaufs der Hauptschleife, um Helligkeitsschwankungen durch verschiedene Programmteile zu vermeiden.
| '5 Ports für Anzeige VQC10 Stellen + 1 Port Stelle Enable Config Portc.5 = Output ' Ausgang Stelle 1 Config Portc.6 = Output ' Ausgang Stelle 2 Config Porta.7 = Output ' Ausgang Stelle 4 Config Porta.6 = Output ' Ausgang Stelle 8 Config Porta.5 = Output ' Ausgang Stelle 16 Config Porta.0 = Output ' Ausgang Stelle Enabled '3 Ports für Anzeige für VQC10 Zeilen + 1 Port Zeile Enable Config Porta.4 = Output ' Ausgang Zeile 1 Config Porta.3 = Output ' Ausgang Zeile 2 Config Porta.2 = Output ' Ausgang Zeile 4 Config Portc.7 = Output ' Ausgang Zeile Enabled '5 Ports für Anzeige für VQC10 Daten Config Portb.2 = Output ' Ausgang Daten 1 Config Portd.5 = Output ' Ausgang Daten 2 Config Portd.4 = Output ' Ausgang Daten 3 Config Portd.3 = Output ' Ausgang Daten 4 Config Portb.3 = Output ' Ausgang Daten 5 'Variablen für Anzeige dimensionieren Dim Stelle As Byte ' Variable für Stellennummer Dim Zeilenr As Byte ' Variable für Zeilennummer Dim Daten(33) As Byte ' Variable für Daten eine Zeile a 5 Pixel Dim Helligkeit As Word ' Anzeigehelligkeit Dim Hell_schnitt As Word ' Anzeigehelligkeit Dim Helligkeit1 As Word ' Anzeigehelligkeit Dim Helligkeit_eram As Eram Word ' Anzeigehelligkeit im EEPROM If Helligkeit >= 2500 Then ' Fehler abfangen Helligkeit = 1000 Helligkeit_eram = Helligkeit EndIf Dim Hell_auto As Byte ' Anzeigehelligkeit Automatik ein/aus Dim Hell_auto_eram As Eram Byte ' Anzeigehelligkeit Automatik EEPROM Hell_auto = Hell_auto_eram ' Automatik aus EEPROM lesen If Hell_auto >= 2 Then ' Fehler abfangen Hell_auto = 0 Hell_auto_eram = Hell_auto EndIf Dim Hell_count As Byte ' Zähler für Durchschnitt Dim Hell_loop As Byte Dim Hell_schwell As Word ' Schwellwert für LED + Relais Automatik Dim Hell_schwell_eram As Eram Word ' Schwellwert für LED + Relais Automatik EEPROM Hell_schwell = Hell_schwell_eram ' Schwellwert aus EEPROM laden If Hell_schwell >= 2500 Then ' Fehler abfangen Hell_schwell = 1000 Hell_schwell_eram = Hell_schwell EndIf Dim Hell_ds(8) As Word ' Array für Durchschnitt Dim Hell_mod As Byte ' Rest Division Dim Scroll As Byte ' durchlaufender Zähler für Laufschrift Dim Zeichenascii As Word ' ASCII Wert von Zeichen Dim Laufzeit As Word ' Zeit für einen Programmdurchlauf Dim Anzeigezeit As Word ' Zeit für Anzeige hell Dim Zeichen As String * 1 ' String für ein Zeichen Dim Zeile As String * 32 ' String für komplette Zeile 'Timer 3 - zählt Mikrosekunden für Anzeigehelligkeit Config Timer3 = Timer , Prescale = 8 ' zweiter 16-bit-Timer, 8000000/8=1 MHz = 1 Mikrosekunde  | 
  
Was zur Anzeige kommen soll, schreibt das Programm in die Zeichenkette "Zeile" (String mit 32 Stellen). Ich beschreibe hier nur beispielhaft eine Anzeigevariante, bei der eine komplette Zeile mit Wochentag, Datum und Uhrzeit angezeigt wird. Die Anzeige wechselt sonst im Betrieb zwischen Temperatur, nächster Weckzeit, Radiofrequenz oder Sendername. Bei der Programmierung habe ich bemerkt, das es sinnvoll ist, den String möglichst von links nach rechts auzubauen. Der Einsatz des Befehls "Mid(variable,x,y) ist ziemlich speicher- und rechenintensiv. Da zeitgleich hier aber über 1000 Leuchtdioden multiplex angesteuert werden und die Anzeige nicht flackern sollen, kommt es auf jede Mikrosekunde an.
|             If Anzeige = 0 Then                             ' ANZEIGE WOCHENTAG LANG, DATUM LANG Zeile = Lookupstr(wt , Wochentag) ' Wochentag String einfügen Zeile = Zeile + Space(1) If Wt = 0 Then ' Montag 6 Zeichen Zeile = Zeile + Space(1) End If If Wt = 3 Or Wt = 5 Then ' Donnerstag + Sonnabend Zeile = Zeile + Date$ ' Datum einfügen Else ' Montag, Dienstag, Mittwoch, Freitag, Sonntag Zeile = Zeile + Left(date$ , 6) ' Tag.Monat. einfügen Zeile = Zeile + "20" ' 20 einfügen Zeile = Zeile + Right(date$ , 2) ' Jahr einfügen End If If Wt = 0 Or Wt = 4 Or Wt = 5 Or Wt = 6 Then ' Montag, Freitag, Sonnabend, Sonntag Zeile = Zeile + Space(1) EndIf Zeile = Zeile + Space(1) End If  | 
  
Jetzt folgt die eigentiche Ansteuerung und Helligkeitsregelung der Anzeige. Praktisch erfolgt die Steuerung der Anzeige so, das während eines Programmdurchlaufs eine komplette Zeile (32 Stellen) der Anzeige mit Daten gefüllt wird, dann wird die Anzeige dieser Zeile  eingeschaltet, es folgt ein Programmdurchlauf der Hauptschleife + Wartezeit für Helligkeitsregelung, jetzt wird die Zeilennummer erhöht, anschließend wieder die Zeile mit neuen Daten befüllt, Zeile wird eingeschaltet,  Programmdurchlauf + Wartezeit,  Zeilennummer erhöhen usw. bis alle 7 Zeilen angezeigt wurden. Dann beginnt das Spiel wieder mit der ersten Zeile.
In den ersten beiden Zeilen wird die Zeilennummer der anzuzeigenden Zeile erhöht bzw. wieder auf 1 gesetzt. Wenn eine große Helligkeit der Anzeige erforderlich ist, erfolgt die Zuweisung der Daten anschließend noch in der Hellphase der Anzeige (lange Laufzeit = große Helligkeit). Falls das Radio eingeschaltet ist, wird anschließend der Mindestwert für die Helligkeit auf 1000 gesetzt. In der nächsten Zeile wird die Laufzeit einer kompletten Hauptschleife aus Timer 3 in Mikrosekunden übernommen. Falls diese kleiner ist als die geforderte Helligkeit der Anzeige, wird das Programm bis zum Erreichen der Anzeigezeit gestoppt (Zeile immer noch hell gesteuert). Erst nach Ablauf dieser Wartezeit wird die Anzeige abgeschaltet um die Daten für die nächste Zeile laden zu können. Falls die Anzeige relativ dunkel leuchten soll, erfolgt die Zuweisung der Daten für eine Zeile erst jetzt in dieser Schleife, in der auch die Daten direkt auf die Portleitungen ausgegeben werden. Anschließend wird der Timer neu gestartet und entsprechende Zeilenleitung angesteuert.
| 'Anzeigeroutine Incr Zeilenr ' Zeilennummer um 1 erhöhen If Zeilenr >= 8 Then : Zeilenr = 1 : End If ' Zeilen 1 bis 7 Stelle = 32 ' Stellennummer auf 32 setzen If Helligkeit >= 1800 Then Do Zeichen = Mid(zeile , Stelle , 1) ' Zeichen Stelle aus Zeile ermitteln Daten(33) = Asc(zeichen) ' ASCII von Zeichen Stelle Zeichenascii = Daten(33) * 7 ' ASCII 29 beginnt an Pos 7, 30 bei 14 usw. Zeichenascii = Zeichenascii + Zeilenr ' Zeile addieren Daten(stelle) = Lookup(zeichenascii , Zeichensatz) ' 5 Datenbits aus Zeichensatz holen Decr Stelle ' Stellennummer um 1 erhöhen Loop Until Stelle = 0 ' ">=" schneller als "=" oder ">" Stelle = 32 ' Stellennummer auf 32 setzen End If If Portd.1 = 1 Then ' wenn Relais für Radio an PortD.1 eingeschaltet If Helligkeit < 1000 Then Helligkeit1 = 1000 ' Helligkeit auf Mindestwert 1000 End If Else Helligkeit1 = Helligkeit End If Laufzeit = Timer3 ' Zeit für 1 Programmdurchlauf aus Timer 3 übernehmen If Laufzeit < Helligkeit1 Then ' wenn es länger dauert, nicht warten Anzeigezeit = Helligkeit1 - Laufzeit ' Anzeigezeit errechnen Waitus Anzeigezeit ' wait mit Variable erst ab Version 1.12.x.x!!! End If Portc.7 = 1 ' ZeileCE - Zeile ausschalten Do If Helligkeit < 1800 Then If Stelle >= 1 Then Zeichen = Mid(zeile , Stelle , 1) ' Zeichen Stelle aus Zeile ermitteln Daten(33) = Asc(zeichen) ' ASCII von Zeichen Stelle Zeichenascii = Daten(33) * 7 ' ASCII 29 beginnt an Pos 7, 30 bei 14 usw. (7 Zeilen) Zeichenascii = Zeichenascii + Zeilenr ' Zeile addieren Daten(stelle) = Lookup(zeichenascii , Zeichensatz) ' 5 Datenbits aus Zeichensatz holen End If End If Porta.0 = 1 ' StelleCE - Stelle ausschalten, H an cp VQC10 Portb.2 = Daten(stelle).4 ' Datenbit 1 ausgeben Portd.5 = Daten(stelle).3 ' Datenbit 2 ausgeben Portd.4 = Daten(stelle).2 ' Datenbit 3 ausgeben Portd.3 = Daten(stelle).1 ' Datenbit 4 ausgeben Portb.3 = Daten(stelle).0 ' Datenbit 5 ausgeben, fertig Decr Stelle ' Stellennummer um 1 verringern Portc.5 = Stelle.0 ' Stellenbit 1 ausgeben Portc.6 = Stelle.1 ' Stellenbit 2 ausgeben Porta.7 = Stelle.2 ' Stellenbit 4 ausgeben Porta.6 = Stelle.3 ' Stellenbit 8 ausgeben Porta.5 = Stelle.4 ' Stellenbit 16 ausgeben Porta.0 = 0 ' StelleCE - Stelle gültig, L an cp VQC10 Loop Until Stelle = 255 ' Schleife verlassen Timer3 = 0 ' Timer für Laufzeit starten Porta.4 = Zeilenr.0 ' Zeilenbit 1 ausgeben Porta.3 = Zeilenr.1 ' Zeilenbit 2 ausgeben Porta.2 = Zeilenr.2 ' Zeilenbit 4 ausgeben  | 
  
Im weiteren Verlauf erfolgen noch einige selten auszuführende Aktionen, die ohnehin in der Dunkelphase der Anzeige erfolgen sollen, weil sie eine zu lange Laufzeit haben und dadurch die Anzeige zum Flackern bringen. Anschließend wird die Zeile eingeschaltet:
|    Portc.7 = 0                                              ' ZeileCE - Zeile gültig und Zeile einschalten | 
  
Das ist die Tabelle für die Wochentage in Langform:
| Wochentag: Data "Montag" , "Dienstag" , "Mittwoch" , "Donnerstag" , "Freitag" , "Sonnabend" , "Sonntag"  | 
  
Der Zeichensatz für die 5*7 Matrix mußte selbst erstellt werden. Das lässt sich relativ komfortabel direkt in BASCOM erledigen. Dafür existiert dort ein Werkzeug namens "LCD-Designer". Man muss dessen Ausgabe nur an die hier erforderlichen 7 Zeilen anpassen. Hier ein Auszug aus der kompletten Zeichensatz-Tabelle:
| Zeichensatz: Data 14 , 17 , 17 , 14 , 17 , 17 , 14 ' 8 ASCII 056 Data 14 , 17 , 17 , 15 , 1 , 2 , 12 ' 9 ASCII 057 Data 32 , 32 , 4 , 32 , 32 , 4 , 32 ' : ASCII 058 Data 32 , 32 , 32 , 32 , 6 , 2 , 4 ' ; ASCII 059 Data 32 , 2 , 4 , 8 , 4 , 2 , 32 ' < ASCII 060 Data 32 , 32 , 14 , 32 , 14 , 32 , 32 ' = ASCII 061 Data 32 , 8 , 4 , 2 , 4 , 8 , 32 ' > ASCII 062 Data 14 , 17, 1 , 2 , 4 , 32 , 4 ' ? ASCII 063  |