Pfad:
Home =>
AVR-DE =>
Anwendungen => RGB-Ticker m8
 |
AVR-Anwendungen
RGB-Ticker 8x8 mit ATmega8
Hardware, Aufbau, Anwendung und Software für den RGB-Ticker |
 |
RGB-Ticker ATmega8
- Eigenschaften
- Hardware
- Aufbau
- Software
- RGB-Designer
Diese Seiten als PDF
(20 Seiten, 1,3 MB).
64 LEDs, jede mit drei Farben macht 192 PWM-Ansteuerungen mit je 256 Stufen
macht zusammen 49.152 Vergleiche pro Durchlauf, und das mit 50 oder 100 Hz
Multiplexgeschwindigkeit! Geht das überhaupt mit einem einzigen
Mikroprozessor oder braucht man dazu eine ganze Farm derer? Ja, es geht,
und zwar schon ab popeligen 2 MHz Takt, aber nur in Assembler.
Die Hardware-Eigenschaften des beschriebenen RGB-Tickers:
- Steuert 8x8 = 64 RGB-Leuchtdioden mit 256 stufigem PWM-Wert für
die rote, grüne und blaue Farbkomponente an (192 Pulsweitenmodulatoren,
alle 16.777.216 Farben mit jeder LED darstellbar).
- Frei programmierbarer Text im Flash-Speicher des Controllers wird
mit per Software-Einstellung beliebig festlegbarer Geschwindigkeit
langsamer oder schneller über die Anzeigefläche geschoben.
- Mehr als 300 Spalten können im Flash-Speicher des Prozessors
gespeichert und zur Anzeige gebracht werden. Das entspricht ca.
37 Buchstaben zu je 8 Spalten, bei kleinerer Schrift
(z. B. 5*7) entsprechend mehr. Wer noch mehr braucht, um
einen Roman anzuzeigen, verwendet einen ATmega16 oder ATmega64
mit noch mehr Flash-Speicher und baut das Schaltbild und die
Software etwas um.
- Stand-alone, braucht keinerlei zusätzliche Hardware und nur
den Netzspannungsanschluss mit 230 V, daher auch außer Haus
und ohne weiteren Rechner einsetzbar (nein, dieses Teil braucht
keinen zusätzlichen Arduino-Verbau um zu funktionieren!).
- Einstellbare Multiplex-Frequenz mit einem Default von 150 Hz,
arbeitet auch ab 2 MHz Prozessortaktfrequenz mit 50 Hz
Multiplexfrequenz korrekt (entspricht 200 Hz pro Ausgabespalte).
Höhere Multiplexfrequenzen bei 16 MHz Prozessortakt sind
ebenfalls möglich und können per Software-Änderung
eingestellt werden.
- Gut dokumentierter freier Assembler-Quellcode, leicht
modifizierbar für andere Taktfrequenzen und anpassbar an
andere Prozessortypen.
- Freie Software in Lazarus-Pascal zum komfortablen Design von
Farbabläufen und Texten sowie einfacher Import in den
Assembler-Quellcode.
- Einfach in der fertigen Schaltung umprogrammierbar mit der
eingebauten ISP6-Schnittstelle, daher kommt kaum Langeweile auf.
2.1 Prozessorteil
Dies ist der Prozessorteil des Schaltbilds. Es zeigt den Controller
ATmega8 im 28-poligen PDIP-Gehäuse. Er wird mit einem Quarz
von 16 MHz getaktet (verwendbar sind alle Quarze ab 2 MHz
aufwärts, seine Frequenz ist im Assembler-Quellcode anzugeben
und neu zu assemblieren).
Die folgenden Ports des ATmega8 erfüllen folgende Aufgaben:
- Die unteren vier Bits im Port B schalten die Transistoren der
vier Kathodentreiber ein und aus. Es ist jeweils nur eines der
vier Bits aktiv. Während des Schreibens der Anodenspeicher
ist keines der vier Bits an. PB3 (Doppelnutzung für ISP
unproblematisch), PB4 und PB5 sind noch mit dem ISP6-Stecker
verbunden, über den der ATmega8 in der fertigen Schaltung
programmiert werden kann.
- Die fünf Bits von Port C steuern die Adressen der
Latch-Enable-Eingänge der fünf Speicher an. Sie sind
aktiv High und schreiben den Inhalt des Datenports D in jeweils
einen der fünf Speicher.
- Alle acht Bits von Port D stellen die Dateneingänge der
Speicher für die Anodentreiber bereit, die mit Latch Enable
geschrieben werden. Nach dem Schreiben der Speicher steuert der
Port die acht rechten blauen Anodentreiber an. Die Anoden werden
mit Nullen ein- und mit Einsen PWM-angesteuert ausgeschaltet.
Soll ein anderer Prozessortyp verwendet werden (z. B. ATmega16
oder ATmega64, um mehr Flash-Speicher nutzen zu können),
müssen diese Ports umkonfiguriert werden. Dabei ist darauf zu
achten, dass die Kathodentreiber- und die Latch-Enable-Ports jeweils
mit Bit 0 beginnen (ansonsten muss die Software entsprechend
umgeschrieben werden. Bei 40-poligen Typen bleiben entsprechende
Portpins ungenutzt. Natürlich muss die geänderte Portbelegung
auch in der Software entsprechend umkonfiguriert werden.
Der Reset-Pin liegt mit 10 k an Plus und ist mit der ISP6-Schnittstelle
verbunden. Die AD-Wandler-Anschlüsse AREF und AVCC werden nicht
benötigt.
Die Stromversorgung des ATmega8 ist mit 5 V verbunden und mit einem
10 nF-Keramikkondensator gegen Stromspitzen im Prozessor geblockt.
Alle Anschlüsse zur Speicher- und Treiberplatine sind an einen
26-poligen Winkelstecker geführt, der mittels Flachkabel mit dieser
verbunden werden kann. Als Stecker sollte in jedem Fall ein Wannenstecker
verwendet werden, damit keine Verpolung erfolgen kann. Die beiden
Versorgungsanschlüsse VCC und GND sind wegen der großen
Ströme vierfach belegt, so dass die Versorgung auch an die
Prozessorplatine angeschlossen werden kann und die Treiber- und
Anzeigeplatine mit versorgt.
2.2 Zwischenspeicher- und Anzeigentreiber-Teil
Dies ist der Speicher- und Treiber-Teil der Schaltung. Er besteht aus
- sechs 8-Bit-Latches 74HCT373, die 14 Controller-Pins zu
48 Anodentreiber-Pins erweitern,
- 48 PNP-Anodentreiber-Transistoren BC557 (verwendbar sind alle
PNP-Kleinsignaltransistor-Typen),
- 48 Widerstände, die die LED-Ströme der drei Farb-LEDs
entsprechend der drei LED-Spannungen auf einheitlich 25,6 mA
einstellen (rot: 100Ω, grün und blau: 68&Omega),
- den vier NPN-Kathodentreiber-Transistoren BD439 (verwendbar sind
alle Typen mit mindestens 1,2 A Schaltvermögen), die
nicht gesondert gekühlt werden müssen, da sie nur Voll-Ein-
oder -Aus ausgesteuert werden. Die vier Basiswiderstände der
Transistoren begrenzen den Basisstrom auf 20 mA.
Die 48 Anodenanschlüsse zur Anzeigenplatine können mit zwei
24-poligen Steckanschlüssen links und rechts realisiert werden.
Für die vier Kathodenanschlüsse kann ein zusätzlicher
8-poliger Stecker (je vier Anschlüsse verbunden) verwendet werden.
Die elendig große Transistor- und Widerstandsfarm ist deswegen
notwendig, weil es Anodentreiber-ICs selbst für nur 25 mA
kaum zu kaufen gibt und weil die 74HCT373 lediglich 6 mA am
Ausgang liefern und das viel zu wenig für eine anständige
LED-Helligkeit ergäbe. Selbst 74244 oder 74373 liefern nur
geringfügig mehr, so dass auch diese nicht als Anodentreiber
in Frage kommen. Die Farm ist leider unvermeidbar.
Die im Datenblatt der RGB-Leds angegebenen typischen Forward-Voltages
der grünen und blauen LEDs von 3,6 V stimmen übrigens
nicht: es sind nur etwa 3,1 V. Folgt man dem Datenblatt, müsste
der Widerstand für grün und blau nur 41 Ω sein.
Die zunächst verbauten 39 Ω erwiesen sich als viel
zu niedrig!
Da zum Treiben der LEDs keine Konstantstromregelung eingesetzt wird
(dafür wären weitere 96 Dioden zu verbauen gewesen), ist
der LED-Strom etwas von der Sättigungsspannung der
Kathodentreiber-Transistoren abhängig, also je nachdem, ob
und wie viele der LEDs und ihrer drei Farben zweier Achterreihen
(Imax = 2 * 8 * 3 * 25 = 1.200 mA) gleichzeitig
eingeschaltet sind. Das Diagramm zeigt die Ströme der drei
Farben einer LED bei 20 bis 1.200 mA Kathodentreiberstrom an.
Die LED-Ströme unterscheiden sich etwas, je nachdem wieviele
LEDs einer Reihe angetrieben werden müssen. Die Grün- und
Blauströme vermindern sich etwas steiler als der Rot-Strom.
Da der Helligkeitseindruck bei 28 mA und 24 mA bzw. 18 mA
aber sehr ähnlich ist, weil die Helligkeit im Sättigungsbereich
der LEDs liegt und auch die Sättigung des menschlichen Auges keine
Unterscheidung mehr ermöglicht. Puristen können entweder
Transistoren mit niedrigerem UCE(sat) verbauen oder den
Unterschied durch Feineinstellung der Farbwerte korrigieren, indem sie
in die RGB-Designer-Software eine feinfühlige
Korrektur einbauen, die genau auswertet welche und wieviele LEDs bei
jedem Multiplexzyklus gleichzeitig eingeschaltet sind und die
Farbwerte entsprechend korrigieren. Man kann auch einen Weißabgleich
durchführen, indem man alle drei Farben auf die gleiche Helligkeit
bringt (aber bitte nicht alle Zeilen gleichzeitig auf 255, das verbrät
zu viel Strom und der Kühlkörper glüht) und schaut, ob sich
die drei Farben zu reinweiß mischen oder einen Rot-, Grün- oder
Blau-Stich haben.
2.3 Displayteil
Dies stellt die Verdrahtung der 64 LEDs dar. Es ist für
RGB-LEDs mit gemeinsamer Kathode ausgelegt. Die R-, G- und
B-Anschlüsse der LEDs der linken vier und der rechten vier
Spalten sind miteinander verbunden, so daß jeweils drei
Signalleitungen nR, nG und nB zu den linken (nRL, nGL und nBL)
und den rechten (nRR, nGR und nBR) Anodentreibern führen.
Die Kathoden sind spaltenweise verbunden, die linken Kathodenreihen
K1 bis K4 sind jeweils mit den rechten Kathodenreihen K5 bis K8
verbunden und werden vom gleichen Kathodentreiber gespeist, der
im Maximalfall (alle Farben beider Spalten voll an) einen Strom
von 3*16*25 mA = 1,2 A treiben können muss.
Der BD239 kann das, aber auch viele andere
NPN-Leistungstransistoren im TO220-Gehäuse.
2.4 Netzteil
Das Netzteil muss folgende Eigenschaften besitzen:
- Es muss stabile 5 V liefern, da der Strom durch die LEDs
über strombegrenzende Widerstände von dieser Spannung
abhängt.
- Da jeweils 16 LEDs mit maximal 25 mA und mit drei
Farben angetrieben sein können (alle LED mit den drei
Farben auf voller Leuchtstärke gleich hellweiß),
beträgt die maximale Strombelastung des Netzteils
1,2 A. Daher muss der Trafo bei 7,5 V Spannung
10 VA leisten.
- Der Spannungsregler muss ebenfalls 1,2 A leisten. Seine
Temperatur muss mit einem Kühlkörper mit einem
Wärmewiderstand von maximal 10 K/W begrenzt werden.
Im Schaltbild ist so ein Standard-Netzteil mit einem 2*7,5 V-Trafo
mit seiner Dimensionierung zu sehen. Die beiden Dioden müssen
eine größere Leistung abkönnen als es eine 1N4001
könnte.
Das hier simuliert das dargestellte Netzteil (siehe die
Power-Supply-Software hier).
Die Spannung am Elko bleibt ohne Last bei deutlich unter 16 V,
deshalb kommen die Elkos mit einer Spannungsbelastbarkeit von 16 V
aus.
Das hier ist die Netzteilspannung bei 1.200 mA Last. Der Elko von
4700 µF ist gerade so ausreichend.
Das Netzteil wurde mit einer Dauerlast von 0,83 und 1,10 A
getestet. Bei 0,83 A tritt keinerlei, bei 1,10 A tritt ein
leichtes Ripple von 0,1 V auf. Sind nicht alle 64 LEDs
gleichzeitig hell rein weiß, dürfte der Elko die
Verbrauchsspitze ausmitteln und das Netzteil ausreichend stabil sein.
Die Temperaturen der zwei Dioden, des Trafos und des Spannungsreglers
bleiben auch im Dauerbetrieb mit 0,83 A unter 40°C, nur der
Kühlkörper wird recht warm und bei 1,1 A auch ordentlich
heiß.
Die Hardware besteht aus drei gestapelten Platinen mit jeweils
100*80 mm Größe:
- im Erdgeschoss die Netzteil- und Prozessor-Platine,
- im ersten Stock die Speicher- und Treiber-Platine, und
- im zweiten Stock die LED-Platine.
Alle Platinen sind Epoxid-Lochraster-Platinen und mit
lötbarem Kupferlackdraht verdrahtet. Die Platinen (1)
und (2) sind einseitig beschichtet, die Platine (3) ist
beidseitig beschichtet (wegen der Stecker nach unten).
Alle Komponenten zusammen belaufen sich auf etwa etwa 75€,
knapp die Hälfte für die RGB-LEDs.
3.1 Netzteil- und Prozessor-Platine
Controller und Netzteil passen auf eine Platine. Der gerippte
Kühlkörper mit 10 K/W und der Spannungsregler
sind mit einer M3-Schraube fest mit der Platine verschraubt,
wegen der erhöhten Temperatur sollte es eine
Epoxid-Ausführung sein, weil Hartpapier bei 50°C arg
altert. Sonst muss man Spannungsregler und Kühlkörper
mit einem Luftspalt etwas erhöht montieren. Vertikale
Montage würde die Gesamthöhe erhöhen.
Der 26-polige Wannenstecker sollte gewinkelt sein, damit er
über den Rand der Platine etwas hinausragt und das
Flachbandkabel zur Speicher-und Treiber-Platine bündig
platziert werden kann. Je zwei M3-Distanzbolzen mit 20 mm
und Innen- und Außengewinde an allen vier Ecken halten
die aufgesetzte Speicher- und Treiber-Platine auf 40 mm
Abstand. Bei aufgestelltem Kühlkörper muss die
Distanz auf 50 mm erhöht werden.
3.2 Speicher- und Treiber-Platine
So sind die Komponenten auf der Speicher- und Treiber-Platine
platziert.
Die zwei oberen 74HCT373 und die acht ungepufferten Datenleitungen
sind für die rechte Displayseite zuständig, die drei
unteren für rechts.
Die Transistoren passen nicht ganz in das Raster und müssen
abwechselnd nach links und nach rechts versetzt montiert werden.
Eine Variante beim Einbau der Transistoren ist es, die Emitter
nicht einzulöten sondern oberhalb der Platine und des
Basiswiderstands abzubiegen und mit dickem Draht zu verlöten.
Die Basiswiderstände können dann direkt an die Basen
herangeführt und die beiden Lötaugen direkt miteinander
verbunden werden. Außerdem kann dann sehr dicker Draht
für die Emitterzusammenschaltung verwendet werden, da
sich die Anodenströme auf insgesamt 1,2 A summieren
können, wenn alle Anoden beider Kathodenreihen eingeschaltet
sind (zu Beginn der PWM-Phase kommt das oft vor und ist sogar
die Regel).
3.3 LED-Platine
Die LEDs sind im Raster angeordnet. Ihre Verdrahtung erfolgt
gemäß Schaltbild.
Die RGB-Dioden passen übrigens so wie hier gezeichnet nicht in
das Lochraster. Die vier Anschlüsse hätten bei Anordnung in einer
Lochreihe nicht auf das 8 cm-Board gepasst. Um eine regelmäßige
Anordnung zu erreichen, wurde entschieden, die vier Anschlüsse
jeder LED auf drei Reihen und drei Spalten zu verteilen, wie das
nebenstehende Bild demonstriert. Jede LED beansprucht daher
7,62 mm Länge und Breite. Jeweils acht davon ergeben
horizontal und vertikal ein Feld von 61 mm * 61 mm
und nutzt daher nicht die gesamte Fläche von 10 * 8 cm aus.
So sieht folglich das gesamte Leuchtfeld mit allen LEDs und einer
passenden Plexiglasabdeckung aus.
Die beiden Pfostenstecker links und rechts sollten exakt in die
entsprechenden Buchsenleisten der darunter liegenden Speicher- und
Treiberplatine passen. Ebenso die vier Kathoden-Pins. Man achte darauf,
keine zu kurzen Pfosten zu verwenden, damit alles passt.
3.4 Aufbaureihenfolge
Bei der manuellen Verdrahtung empfiehlt es sich, die Netzteilplatine
mit dem Prozessor zuerst und danach die LED-Platine fertig zu stellen,
da diese ohne Weiteres gezielt getestet werden können. Die LEDs
zum Beispiel mit einer Spannung von 0 V am Kathodenanschluss
und einem Vorwiderstand von z.B. 100 Ohm an +5 V am
Anodeneingang.
Bei der Verdrahtung der Speicher- und Treiberplatine sollte mit der
Verdrahtung der Latch-Enable-Eingänge begonnen werden und der
rechten Seite der LEDs begonnen werden. Dann sollten nach und nach
die roten, grünen und blauen LEDs der letzten Spalte bestückt
werden, da bei der Bestückung der blauen LEDs in dieser Spalte
auch die Datenleitungen zu den Latches zu verlegen sind. Mit der
vollständigen Bestückung dieser Spalte sind alle
Datenleitungen der Latches verdrahtet und diese können getestet
werden.
3.5 Softwarehilfen für Inbetriebnahmetests
Bei der Verdrahtung der Latches, der Anodentreiber und der LEDs kann
man viele Fehler machen. Um das Finden solcher Fehler zu vereinfachen,
sind in der Software diverse Diagnosemöglichkeiten eingebaut.
Diese können mit Softwareschaltern eingeschaltet werden, mit
Neuassemblieren in Hexcode umgesetzt und testweise in den ATmega
gebrannt werden.
So kann z. B. unter Angabe der LED-Zeile und Spalte und der
Farbe eine ganz bestimmte LED mit einer einzigen Farbe gezielt
eingeschaltet werden. Hat man gerade diese LED verdrahtet, kann
man sie testen. Man beginnt damit nach Bestückung der
ersten drei Anodentreiber in Zeile 1, indem man die Software auf
Row = 1 und Column = 8 der LED-Matrix einstellt und diese nacheinander
auf Rot, Grün und Blau einstellt. Wenn alles richtig war, sollte
die erste LED jetzt in diesen Farben angehen.
Ich habe mit diesem Tool ganz viele Verdrahtungsfehler identifizieren
können und es erwies sich als extrem hilfreich.
Man kann damit auch Ströme durch die LEDs messen: einfach mit
dem Multimeter in der Stromeinstellung den aktiven Anodentreiber mit
dem Multimeter mit dem aktivierten Multiplexausgang verbinden. Nicht
erschrecken, wenn das knapp 50 mA Strom anzeigt: schaltet man
die LED mit der korrekten Farbe dazwischen (Gemeinsame Kathode an
den Multiplex-Pin, Anode rot/grün/blau an den Anodentreiber-Pin),
geht der Strom auf ca. 25 mA zurück.
In dieser Software ist noch ein Gimmick enthalten: man kann
die ausgewählte LED mit der ausgewählten Farbe wahlweise
im 25 mA-Dauerbetrieb und mit 1:4-Multiplexbetrieb laufen lassen,
um zu sehen, ob die Helligkeit im Multiplexbetrieb niedriger ist.
Wie Sie sehen, sehen Sie nix! Erst bei 1:8 (schwach) oder gar bei
1:16 sieht man eine nennenswerte Abnahme der Helligkeit im eingestellten
Sekundentakt.
Mehr zu den Einstellungen der Software ist hier
zu lesen.
Die Hardware-Testschalter schalten den normalen Programmablauf aus und
verzweigen stattdessen zu dem entsprechenden Testcode:
- Die Funktion Debug_SP schaltet die LEDs einer
ausgewählten Spalte 1..8 (Parameter cDbgSPCol zwischen 1 und
8) auf eine ausgewählte Farbe (Parameter cDbgSPColor, 1=rot,
2=grün, 3=blau). Damit kann die korrekte Verdrahtung der
LED-Spalten und LEDs, der Latches und der Kathodentreibertransistoren
überprüft werden.
Im Bild rechts sollte Spalte 1 auf grün geschaltet sein,
tatsächlich sind aber auch noch die unteren fünf roten
LEDs der Spalte 5 auf rot geschaltet. Hier lag ein Kurzschluss
zwischen dem Latch Enable des rechten roten Latches vor. Ohne den
Hardware-Debug dürfte der Fehler kaum zu finden gewesen sein.
- Mit der Funktion „Debug_SL“ kann eine einzelne LED in einer
ausgewählten Zeile (cDbgSLRow, 1..8) und Spalte (cDbgSLCol,
1..8) auf eine vorgewählte Farbe (cDbgSLColor, 1=rot,
2=grün, 3=blau) gesetzt werden.
Im Beispiel war die Reihe 8 in der Spalte 1 auf Rot gesetzt
worden, es ging aber die LED in Reihe 7 an. Selbiges passierte
mit den Reihen 5 und 6. Es stellte sich heraus, dass die
Datenreihen an der 26-poligen Steckverbindung seitenverkehrt
verdrahtet waren. Nach dem Umlöten auf die jeweils andere
Seite des Steckers war dann alles korrekt.
- Die Funktion „Debug_HW“ lässt nacheinander alle Spalten in
rot, grün und blau leuchten. Die Dauer lässt sich mit der
Konstanten cDebug_HW_delay in 10 ms-Schritten wählen.
- Die Funktion „Debug_blueright“ macht einfach nur die letzte Spalte
des Displays blau.
4.1 Warnung!
Zu Beginn der Software-Abteilung ein wichtiger Hinweis an Arduino-sozialisierte
C-Freaks (oder sollte es besser heißen: Arduino-Opfer?), die keine
andere Sprache als C können und Assembler für einen ausgemachten
Blödsinn und für total Retro halten:
Versuche das nicht mit C zu lösen, Du kriegst nur viele graue Haare davon.
Nämlich davon, herauszubekommmen, was der Compiler aus dem Code so alles
macht und vor allem wann und wie lange. Da Du dazu sowieso versiert Assembler
können musst: fange es gleich richtig herum an. Das hier ist ein Projekt,
das nur in Assembler so richtig elegant geht und funktioniert, garantiert.
Der Grund dafür ist, dass die Aufgabe, in weniger als 20 Millisekunden
genau 49.152 Vergleiche auszuführen, nur lösbar ist, wenn man
- die dazu nötigen Prozessortakte genau abzählen und einhalten
kann,
- keinerlei überflüssigen Takt dazwischen einstreut (was C-Compiler
immer ganz gerne gerne tun), und
- alle Ausführungszeiten bei allen Verzweigungen im Programmablauf
peinlich genau einhält.
Wie man das hinkriegt, wird mit dieser Software hier demonstriert.
4.2 Download
(Die Software ist noch nicht final, sie wird nachgeliefert, wenn
qualitätsgesichert)
4.3 Assemblieren
Zum Assemblieren des Quellcodes ist ein Assembler vonnöten, der
.IF-, .ERROR- und .MESSAGE-Direktiven versteht. Der mit dem Studio 4 und
höher ausgelieferte Assembler 2 kann das. Wer nicht mit Windows
arbeitet, kann sich meinen Assembler
gavrasm
entweder als ausführbare Linux-64 Version herunterladen oder für
andere Betriebssysteme den Quellcode dafür und diesen mit FPC kompilieren.
Wie das geht ist hier
näher beschrieben.
Die vom gavrasm ausgegebenen zwei Warnungen kann man ohne Weiteres ignorieren.
Sind Parameter falsch eingestellt, kriegt man Fehlermeldungen.
4.4 Flashen, Fuses
Die vom Assembler produzierte Hex-Datei ist in den Controller zu brennen.
Dafür, dass das in der fertigen Schaltung geht, gibt es den ISP6-Stecker.
Beim Flashen ist noch die Oszillator-Fuse des ATmega8 von der werksseitigen
Einstellung (links) auf den externen Quarz von 16 MHz umzustellen (rechts).
Als Testhilfen sind in der Software die nachfolgend beschriebenen Schalter
eingebaut. Alle Schalter sind auf Eins zu setzen um sie zu aktivieren
und auf Null um sie abzuschalten. Es sollte immer nur einer der
Debugschalter eingeschaltet sein. In der Betriebsversion müssen
alle Schalter auf Null gesetzt werden, damit das Programm normal
abläuft.
- Debug-Schalter zur Software-Simulation im Simulator zur Messung
von Durchlaufzeiten bei den verschiedenen Ablaufarten:
- Debug_Mux: simuliert einen einfachen Multiplex-Durchlauf
mit Abschalten der Kathodentreiber, Ausgabe der Anodentreiberbits
an die Latches und Einschalten des nächsten Kathodentreibers,
- Debug_DelayNormal: simuliert den Ablauf einer normalen
Verzögerungsschleife,
- Debug_PwmCmp: Absolviert einen PWM-Vergleichsdurchlauf
für alle 192 LEDs.
- Debug-Schalter zur Hardware-Überprüfung:
- Debug_singleled: Schaltet eine einzelne auswählbare
LED in wählbarer Farbe an. Auswahl der LED und Farbe mit dem
Konstanten
- cDebugRow: Zeile der einzuschaltenden LED (1..8),
- cDebugColumn: Spalte der einzuschaltenden LED (1..8),
- cDebugColor: Farbe der LED (1=Rot, 2=Grün, 3=Blau).
Mit der Konstanten Debug_w_woMux kann zusätzlich der
LED-Betrieb mit und ohne Multiplex-Schaltung getestet werden. In
diesem Modus schaltet die LED für Debug_w_woMuxDelay
mal 10 ms (100 für eine Sekunde) in den Multiplex-Betrieb
und danach für diesselbe Dauer in den Dauerbetrieb. Wer den
1:4-Multiplexbetrieb durch 1:8 oder 1:16 ersetzen möchte, um
überhaupt einen Effekt zu sehen, sucht die Zeile andi ZL,0x03
und ersetzt 0x03 durch 0x07 bzw. 0x0F.
- Debug_blueright schaltet alle blauen LEDs der Spalte 8
an.
- Debug_hardware: Schaltet nacheinander alle LEDs der
Spalten 1 bis 8 nacheinander auf rot, grün und blau. Der
Parameter Debug_hardware_delay gibt an, nach welcher Zeit
die nächste Farbe bzw. die nächste Spalte eingestellt
wird (in Vielfachen von 10 ms).
Nicht vergessen nach der Änderung mit einem .if-fähigen Assembler
zu assemblieren und nach Ende der Testveranstaltung alle Debug-Schalter
auszuschalten.
4.6 Adressierung der Hardware
Die Organisation der LED-Schaltung in Spalten und Zeilen und nach
den drei Farben ist grundlegend auch für die Software. Daher
hier noch mal ein Überblick. Alle zweistelligen Zahlen sind
in hexadezimalem Format.
Horizontal sind die beiden Parameter MUX und LE wichtig:
- Mux gibt den aktiven Kathodentreiber an und ist für
die Spalten auf der linken und der rechten Seite zuständig,
- LE zeigt auf das aktive Latch, das beschrieben werden
soll. Der Inhalt, mit dem es beschrieben wird, liegt auf dem
Datenbus Data.
In der Software sind Mux und LE in den beiden Registern rMux
und rLE enthalten.
4.7 Optimale Organisation des Speichers
Damit 8 * 8 * 3 = 192 verschiedene
pulsweitenregulierte Signaldauern erzeugt werden können, sind
- die 192 Anodentreiberbits (LED-Farbe an = Null oder aus = Eins) in
24 Bytes im SRAM ab der Adresse sBits: abgelegt:
Die Anordnung der Bytes erfolgt vertikal nach den acht darzustellenden
Spalten und horizontal nach den drei Farben, damit der Schreibprozess
der Anodentreiberbits in die fünf Speicherlatches schnell vonstatten
geht. Rechts ist noch zu sehen, bei welcher Multiplex-Phase welche Bits
in die Latches zu schreiben sind (das sechste Latch ist der Port selbst),
- die 192 Vergleichswerte, die angeben, in welcher PWM-Phase das
zugehörige Anodentreiberbit auf Eins gesetzt und damit die
betreffende LED-Farbe ausgeschaltet werden muss, sind im SRAM ab
Adresse sCmp: abgelegt:
Damit auch hier der Vergleich mit dem aktuellen PWM-Wert schnell geht,
ist hier die gleiche Struktur wie bei den Bits gewählt: horizontal
die acht Zeilen, jeweils mit 8 Bytes für die Farben R, G und B, und
vertikal die acht Spalten.
Mit dieser Grundorganisation ist eine optimierte Gestaltung der Software
möglich.
4.8 Optimierte Ablaufstufen der Software und Taktung
Zur Lösung der Aufgabe ist ein linearer Programmablauf notwendig,
dessen Zeitablauf mit einer Verzögerungsschleife variabler Dauer
eingestellt wird, um alle unterschiedlichen Ausführungszeiten
letztlich auf die gleiche Zeitdauer bringen zu können. Mit Hilfe
der Verzögerungsschleife wird erreicht, dass alle Verzweigungen im
Programm gleich lang dauern. Egal ob
- nur die Anodentreiberbits der beiden nächsten auszugebenden Spalten
an die fünf Latches und das sechste auf den Datenport ausgegeben und
der aktive Kathodentreiber eingestellt werden sollen (ordinäres
Multiplexen), oder ob zusätzlich
- der nächste PWM-Zyklus zu absolvieren ist (alle 192 Anodentreiberbits
sind daraufhin zu überprüfen, ob ihr Vergleichswert erreicht ist -
falls ja: Setzen des Treiberbits auf Eins und damit Ausschalten der
betreffenden LED-Farbe), oder ob zusätzlich
- ein neuer PWM-Zyklus beginnt und alle Anodentreiberbits erst mal auf Null
zu setzen sind (LED voll anschalten), oder ob zusätzlich
- alle Spalten um eine Position nach links zu schieben sind und von rechts
die nächste Spalte aus dem Flash kopiert werden muss,
Der grundlegende Ablauf aller Programmschleifen ist im Diagramm abgebildet.
Es beginnt mit der Einstellung des nächsten Multiplexwertes durch Linksschieben
des Registers rMux, das nacheinander die vier Multiplexkanäle 1+5,
2+6, 3+7 und 4+8 ansteuert. Ist das Bit 5 von rMux nach dem Linksschieben Null,
handelt es sich um eine einfache Multiplex-Operation und die Software verzweigt
zur Multiplex-Ausgabe: nach dem Absolvieren der Verzögerungsschleife mit
dem Zählerwert Delay A werden die Anodentreiberbytes in die Latches
geschrieben:
- zuerst die Kathodentreiber ausgeschaltet (Null in den Kathodentreiberport),
- dann das Latch-Enable-Register rLE auf 1 setzen,
- dann nacheinander die fünf Anodentreiberbytes in die Latches
geschrieben (Ausgabe am Datenport, rLE auf den Latch-Enable-Port schreiben,
Null auf den Latch-Enable-Port schreiben), und
- abschließend das sechste Anodentreiberbyte auf den Datenbus legen.
Danach wird der Kathodentreiber der beiden betreffenden Kanäle
gemäß rMux eingeschaltet. Die Programmschleife beginnt danach
von vorne.
Erreicht Bit 5 von rMux beim Linksschieben zu Beginn der Schleife eine
Eins, dann ist ein Multiplex-Zyklus vorbei und rMux beginnt wieder bei
1 für die Spalten 1+5. Dazu wird nun das Register rPwm um Eins
erhöht und der nächste PWM-Zyklus ausgelöst. Ist rPwm
nicht Null (Ende des PWM-Zyklusses noch nicht erreicht), werden nacheinander
alle 192 Vergleichswerte mit dem aktuellen PWM-Wert verglichen und, bei
Gleichheit, das betreffende Anodentreiberbit auf Eins geschaltet (LED-Farbe
aus). Um den Zeitbedarf für diese Vergleiche zu kompensieren, wird der
Verzögerungs-Wert auf Delay B eingestellt. Der weitere Ablauf ist dann
wie beim normalen Multiplexen.
Hat rPwm beim Erhöhen Null erreicht (von 255 auf 0), ist der
PWM-Zyklus zu Ende und alle Anodentreiber-Bits werden auf Null gesetzt
(PWM-Zyklus-Start). Nun wird der PWM-Wiederholungszähler rRpt
um Eins nach unten gezählt. Falls er nicht Null ist, wird der
gleiche PWM-Zyklus erneut wiederholt und werden alle 256 PWM-Stufen
durchlaufen. Der Verzögerungszähler wird auf den Wert Delay C
gesetzt.
Erreicht rPwm Null, dann
- wird die Adresse des Flashzeigers um eine Spalte erhöht,
überschreitet diese das Ende der gespeicherten Spalten, wird mit dem
Flashspeicher von vorne begonnen,
- werden alle Vergleichswerte in sCmp: um eine Spalte nach links
verschoben,
- wird die letzte Spalte in sCmp: mittels LPM aus dem Flash
geladen, und
- wird der Verzögerungswert Delay D eingestellt.
Der weitere Ablauf erfolgt dann wie gehabt mit Verzögerungsschleife,
Anodentreiberausgabe und Kathodentreiber-Einstellung auf rMux.
4.9 Defaultwerte der Software und Taktung
In der folgenden Tabelle sind alle Default-Einstellwerte der Software
übersichtlich zusammengestellt. Die Einstellwerte können vor
dem Assemblieren mit dem Editor geändert werden.
Als Auswahl für die Taktfrequenz sind 2/4/8/16 MHz dargestellt.
Bei Taktfrequenzen unter 2 MHz funktioniert die Software nicht, weil
die verfügbaren Zeittakte nicht ausreichen. Möglich sind aber alle
Taktfrequenzen oberhalb von 2 MHz, auch alle krummen.
Bitte beachten: die Anzahl Takte pro Runde ergibt sich nicht einfach aus
dem Prozessortakt, der MUX-Frequenz und dem Speedfaktor, sondern bildet
die Ganzzahlenmathematik des Assemblers ab (mit allen Rundungsvorgängen).
Wer einen krummen Quarz verwenden will, findet die Tabellenkalkulation
für das gesamte Projekt als
Open-Office-Tabelle. Einfach in alle grün
hinterlegten Felder die eigene Einstellung eingeben und durch Herumspielen
mit den Einstellungen dafür sorgen, dass keine Werte negativ werden.
Es umfasst auf weiteren Blättern auch noch weitere Berechnungen,
z. B. der Led-Widerstände, der Kühlkörper-Temperatur
und der Maximallast zu PWM-Beginn.
Die MUX-Frequenz umfasst vier Durchläufe der Multiplexschleife. Sie ist
bei 2 MHz per Default auf 50 Hz eingestellt, kann aber auch
größer sein. Allerdings gehen Erhöhungen auf Kosten der
Tickergeschwindigkeit. Bei den höheren Taktfrequenzen sind etwas
höhere MUX-Frequenzen eingestellt.
Der Beschleunigungsfaktor (Konstante speedfactor) verkürzt die
Dauer pro MUX-Durchlauf auf entsprechend kürzere Zeiten, so dass für
die Einstellung der Tickergeschwindigkeit (Konstante cRpt mehr
Geschwindigkeit und eine feinfühligere Einstellung möglich wird.
Ist die eingestellte Kombination nicht möglich, weil sie den
verfügbaren Zeitrahmen überschreitet, wird beim Assemblieren eine
entsprechende Fehlermeldung ausgegeben.
Aus den drei Werten f für die Taktfrequenz in MHz, MUX für die
MUX-Frequenz in Hz und dem Beschleunigungsfaktor speedfactor ergeben
sich nach der Formel
T (Takte) = 1.000.000 * f / MUX / speedfactor
die Anzahl Prozessortakte, die pro Loop-Runde zur Verfügung stehen.
In der Tabelle der notwendigen Takte stehen die Anzahl Takte, die für
die Erledigung der jeweiligen Aufgabe benötigt werden. In der Spalte
Gesamt stehen die Anzahl Takte aufsummiert, die bei dem entsprechenden
Rundendurchlauf benötigt werden. Zusätzlich ist noch die Anzahl
Takte angegeben, über die die Kathodentreiber während des
Schreibens der Speicherlatche abgeschaltet sind (woraus sich durch Teilen
durch die Taktzyklen pro Runde das Kathodenabschaltdauer-Verhältnis
in der letzten Tabellenzeile ergibt).
In den nachfolgenden Zeilen sind die Anzahl Wartetakte für die vier
Verzweigungen angegeben. Sie ergeben sich durch Subtraktion der notwendigen
Takte von den Taktzyklen pro Runde. Aus den Wartetakten ergibt sich für
die 16-Bit-Verzögerungsroutine
Delay:
sbiw R24,1 ; Abwaerts zaehlen, +2 Takte = 2
brne Delay ; Weiter zahelen, +1 = 3 am Ende, +2 = 4 fuer nicht beendet
mit der Formel
N = 4 * (Z - 1) + 3 = 4 * Z - 1
die Anzahl Takte N aus dem Schleifenzähler Z und, durch Umformung,
die Gleichung
Z = (N + 1) / 4
für die Berechnung des Schleifenzählers Z aus der Anzahl Takte N.
Die Zahlenwerte sind in der Software als Konstanten mit der Benennung
cDlyA bis cDlyD angegeben. An den Zahlen sieht man, dass beim
Spaltenwechsel nur recht kurze Verzögerungszeiträume übrig
bleiben. Werden Werte negativ, muss der Beschleunigungsfaktor oder die
MUX-Frequenz verringert werden. Werte kleiner 10 sollten vermieden werden,
da Verzögerungen bei kleineren Nebenabläufen durch Abziehen von
der Konstante kompensiert werden.
Die möglichen Wiederholraten für PWM-Durchläufe sind für
etwa eine Sekunde bemessen angegeben. Linear schnellere oder langsamere
Schiebegeschwindigkeiten im Display kriegt man durch Absenken oder Erhöhen
der Konstante cRpt hin.
Viel Erfolg beim Optimieren, Experimentieren und Anpassen an den eigenen
Bedarf und Geschmack.
Es wäre etwas mühsam, 8 kByte Flash-Speicher mit .db-Direktiven
manuell zu füllen und den sich bewegenden Text als Zahlenwerte mit .db in
den Quelltext einzugeben. Obwohl das natürlich auch ginge ...
Mit dem rgb_designer geht das rapp-zapp, ein bisschen Handarbeit ist aber
noch nötig. Nach dem Start meldet sich das Programm mit einem leeren
Speicher (alle LEDs im 8x8-Matrixfeld sind schwarz).
Das Programm ist in Lazarus-Pascal geschrieben. Den Quellcode gibt es
hier, die ausführbare Programmdatei
für Windows-64-Bit hier.
Klickt man auf eine der 64 Leuchtdioden-Symbole in der Matrix,
öffnet sich ein Farbauswahldialog. Stellt man dort eine andere Farbe
ein und schließt den Dialog mit Ok, dann ändert sich
die Farbe dieser Diode entsprechend.
In den beiden Sektionen Color 1 und Color 2 lassen sich
zwei Farben voreinstellen. Entweder
- man klickt auf das runde Symbol und wählt im Farbdialog eine
Farbe aus,
- man gibt eine RGB-Kombination als Zahlen in die drei Eingabefelder
ein, oder
- man erhöht oder senkt die Helligkeit der drei Farben mit den
Auf-/Ab-Pfeilen rechts neben den Eingabefeldern.
Die eingestellte Farbe erscheint im runden Feld links oben.
Mit dem Knopf to position wird die eingestellte Farbe an diejenige
Position der Matrix kopiert, die mit dem horizontalen und dem vertikalen
Schieberegler in der Gruppe 8-by-8 matrix eingestellt ist.
Entsprechend färben die Knöpfe to column die gesamte
mit dem Horizontalregler eingestellte Spalte, to row die gesamte
Zeile mit dieser Farbe. to all macht die gesamte Matrix mit dieser
Farbe bunt.
Umgekehrt entnimmt der Knopf Pick die Farbe an der eingestellten
Position als aktuelle Farbe, mit der dann weitergearbeitet werden kann.
Um weitere Spalten zu erzeugen, gibt es den Knopf Add. Er fügt
eine Spalte hinzu (sofern das noch in den Flashspeicher des Prozessors
passt) und kopiert den Inhalt der letzten Spalte der Matrix in die
hinzugefügte Spalte. Mit dem Schieberegler in der Gruppe
Columns kann man die anzuzeigenden acht Spalten der Matrix
auswählen. Das Nur-Lese-Eingabefeld zeigt immer die Nummer der
linkesten angezeigten Spalte an.
Maximal können mit dem ATmega8 328 solcher Spalten gespeichert werden.
Dabei sind 300 Bytes für das Programm reserviert. Wählt man
in der Gruppe Project einen anderen AVR-Typ aus dem Aufklappfeld
Device aus, kann man mehr Spalten einstellen. Allerdings muss dann
auch das Programm an den anderen Prozessor angepasst werden.
Der Projektname im Eingabefeld Name kann frei gewählt werden.
Es sollten nur in Dateinamen zulässige Zeichen verwendet werden. Der
Knopf Save sichert die eingestellten Farbspalten in einer Tabelle
auf der Festplatte. Es handelt sich um eine reine Textdatei mit dem
Dateityp .inc, die direkt mit der Direktive .include "name.inc"
in den Assembler-Quellcode eingelesen werden kann. Sie beginnt mit dem Label
RGBTable: und endet mit dem Label RGBTableEnd:. Für
jede Spalte werden acht Bytes Rot-Werte, acht Bytes Grün-Werte und
acht Bytes Blau-Werte geschrieben und vom Assembler in den Flash-Speicher
übernommen. Der Name der Datei entspricht dem eingegebenen
Projektnamen, der Speicherort ist grundsätzlich das Verzeichnis, in
dem der rgb_designer liegt. Als Beispiel ist die Datei TQBFJOTLD.inc
im gezippten Quellcode enthalten.
Mit dem Knopf Load können bereits gespeicherte Dateien
eingelesen und erneut editiert und unter gleichem oder anderem Namen
wieder abgespeichert werden. Mit dem sich öffnenden Dateidialog
kann die Datei auch in ein anderes Verzeichnis abgelegt werden.
Clear verwirft nach Rückfrage und gegebenenfalls Speichern
alle Änderungen und beginnt von Neuem.
In der Gruppe Text kann
- die Textfarbe und die Hintergrundfarbe mit den beiden
Farbwahlknöpfen eingestellt werden,
- der zu schreibende Text im Eingabefeld editiert werden (das
Eingabefeld Width zeigt dabei an, wie viele Spalten dieser Text
hätte),
- durch Klicken mit der Maus in das Eingabefeld Font kann der
Font, Textauszeichnungen und die Zeichengröße
ausgewählt werden, wobei Zeichengrößen maximal 8 sein
dürfen, weil sonst nur die oberen Teile der Buchstaben zu sehen
wären, bei der Größe 7 fehlen bei manchen Fonts
Unterlängen (wie bei g, p oder q), 6 ist oft eine gute Wahl,
- im Eingabefeld ColStart kann die Spalte eingestellt werden,
ab der der Text beginnen soll,
- durch Klicken auf den Knopf Paint kann der Text in
vergrößertem Format im Feld darüber darstellt werden,
- mit dem Knopf 2Colors erreicht werden, dass nur die Vorder-
und Hintergrundfarbe verwendet und alle anderen Farben in diese beiden
umgewandelt werden (vergrößerte Darstellung im Feld
darüber, rückgängig machbar mit erneutem Paint),
- der Knopf Add benutzt werden, um den Text in der aktuellen
Form in die Spalten einzufügen (Achtung! Überschreibt
ohne Rückfrage vorhandene Daten in den Spalten!).
Der Default-Text zeichnet sich dadurch aus, dass er alle Buchstaben des
Alphabets mindestens einmal enthält.
In der Sektion Currents werden die Ströme durch die
Leuchtdioden berechnet. Dazu sind die Vorwärts-Spannungen der drei
Farben bei 25 mA LED-Strom in die Eingabefelder in Volt einzugeben.
Ferner die drei Widerstände in den Anodentreiberstufen. Die
Default-Einstellung entspricht den von mir verwendeten Dioden und der
abgebildeten Schaltung.
Für die abgebildete 8x8-Matrix sind die Ströme in den vier
Multiplexphasen und als Durchschnitt (Average) angegeben. Duch
Ändern der dargestellten Spalte können alle Ströme bei
allen Teilbildern angesehen werden.
Der Knopf Calc bewirkt eine Berechnung aller im Spaltenfluss
auftretenden Ströme, findet den maximal aufretenden Mittelwert
(und die zugehörige Spalte) und mittelt die Ströme. Mit der
Formel P = U * I kann daraus die Leistung im
Dauerbetrieb berechnet werden.
Da die Sättigungsspannung des Kathodentreiber-Transistors BD439
von einigem Einfluss auf den LED-Strom ist, wurde diese Spannung
mit der nebenstehenden Funktion angenähert. Wer einen anderen
Transistor verwenden will muss diese Funktion im Quellcode ändern.
Noch ein wichtiger Hinweis zum Lazarus-Quellcode, der mich drei Tage
lang ziemlich geärgert hat, bis ich es dann doch hingekriegt habe.
Damit für die 64 LED-Shapes nur eine einzige Behandlungsroutine zu
schreiben war, habe ich anfangs mit dem Mouse-Down-Event versucht
herauszufinden, welches der 64 Shapes den Event ausgelöst hat.
Bei den ersten beiden Mausklicks auf die Shapes funktioniert das auch,
bei allen weiteren Klicks wird aber nicht mehr der Sender angegeben:
es bleibt immer der gleiche. Nachdem ich nicht mehr den Mouse-Down-Event
sondern den Mouse-Up-Event auswerte, hat sich dieses rätselhafte
Verhalten in Luft aufgelöst und es funktioniert korrekt.
Als kleines Gimmick erzeugt das Feld Rainbow: den Farbverlauf
eines Regenbogens. Mit der Eingabe eines Addierers kann der belegte
Speicher beeinflusst werden. Sie bewirkt, dass die drei Farben in
diesen Schritten angenähert wird. Je größer die Zahl
desto weniger Spalten sind nötig und je kleiner ist der
Speicherbedarf. Addierer größer als 64 setzen den Addierer
auf Eins zurück und füllen den Speicher so weit wie
möglich. Löschen der Zahl im Eingabefeld oder Setzen auf
Eins bewirkt, dass die minimalste Zahl ermittelt und hier eingetragen
wird. Addierer unter 3 sind beim ATmega8 nicht möglich, kleinere
Zahlen werden auf drei gesetzt.
Die Include-Datei rainbow.inc zeigt, wie die
RGB-Farben sich zwischen den Regenbodenfarben stufenweise annähern.
Lob, Tadel, Fehlermeldungen, Genöle und Geschimpfe oder Spam bitte über
das Kommentarformular an mich.
©2018 by http://www.avr-asm-tutorial.net