Pfad: Home => AVR-DE => Anwendungen => Eieruhr RGB M8515   This page in english: Flag EN Logo
RGB-Eieruhr klein AVR-Anwendungen

Eieruhr RGB mit ATmega8515
Hardware, Aufbau, Verwendung und Software für eine 11-Minuten-Eieruhr

Eieruhr RGB mit ATmega8515

  1. Eigenschaften
  2. Hardware
  3. Aufbau
  4. Software
  5. Fazit
Diese Seite beschreibt einen Timer, der mit 11 farbigen RGB-LEDs arbeitet. Er kann zur Überwachung des Kochvorgangs von Eiern dienen.



1 Eigenschaften der Eieruhr mit ATmega8515

Die Eigenschaften der Eieruhr sind: Entschuldigung: Ich habe mehrfach versucht, von der Eieruhr ein Video anzufertigen. Wegen des 60-Hz-PWM-Zyklusses der Eieruhr ist mir das mit meiner Fuji nicht gelungen, es gibt nur hässliches Flimmern und einen unerträglichen Sound. Nichts was man gerne auf seiner Webseite haben mag.

Seitenanfang Eigenschaften Hardware Aufbau Software Fazit

2 Hardware

2.1 Auswahl des AVR-Typs

Auswahl des ATmega8515 Der Zugriff auf 10 oder 11 RGB-LED-Dioden braucht mindestens vier ganze 8-Bit-I/O-Ports (30 bis 33 I/O-Pins). Zusätzliche Pins sollten es ermöglichen
  1. Töne auf einem angeschlossenen Lautsprecher auszugeben,
  2. eine Taste zum Start und Stop des Timers anzuschließen.
Um den optimalen AVR-Typ für diese Aufgaben zu finden, der all dies möglich macht, habe ich die benötigten Komponenten in die Typauswahl-Sektion des Simulators avr_sim gefüttert. Nur die folgenden Typen ermöglichen es, vier komplette I/O-Ports für die LED-Ansteuerung zu reservieren:
==> ATmega <==
ATmega16 - PDIP40
ATmega16A - PDIP40
ATmega32 - PDIP40
ATmega32A - PDIP40
ATmega83 - PDIP40
ATmega161 - PDIP40
ATmega162 - PDIP40
ATmega163 - PDIP40
ATmega323 - PDIP40
ATmega8515 - PDIP40
ATmega8535 - PDIP40
Schon die zusätzliche Anforderung, einen INT-Eingang für die Taste zu reservieren schränkt die Auswahlmöglichkeiten radikal ein:
==> ATmega <==
ATmega161 - PDIP40
ATmega162 - PDIP40
ATmega8515 - PDIP40
Wenn man nun noch einen OC-Pin für den Lautsprecher anfordert, leert sich die Liste vollständig, da die meisten OC-Pins in der Mitte von I/O-Ports angesiedelt sind. Die einzige Möglichkeit, die geht, ist OC1B in den oben genannten drei Typen.

Da der ATmega161 nicht mehr produziert wird, bleiben ATmega162 und ATmega8515. Ich habe den ATmega8515 gewählt, weil der leicht zu beschaffen ist.

Der Typselektor vom avr_sim zeigt rechts auch die Pinbelegung des ATmega8515 an. Nur ein Pin (PE1) bleibt übrig.

2.2 Schaltbild

Schaltbild der Eieruhr Das Schaltbild zeigt, wie die 11 RGB-LEDs an die 32 I/O-Pins des ATmega8515 angeschlossen sind: jeder Ausgang kriegt einen farb-spezifischen Widerstand und wird an die Kathode der LEDs angeschlossen, in der Reihenfolge blau-grün-rot mit steigender Bit-Nummer. Die Widerstände bestimmen den Strom durch die Farb-LEDs. Alle LEDs sind mit gemeinsamer Anode, die alle an die positive Betriebsspannung angeschlossen sind. Wenn Du LEDs mit gemeinsamer Kathode verwenden willst: geht auch, dann
  1. müssen die Kathoden an Minus, und
  2. in der Software müssen alle Pins mit ihrem PORTcn (c=A/B/C/D, n=0..7) auf eins gesetzt werden.


Der Lautsprecher ist über einen 47 µF-Elko angeschlossen. Er rumort dann sehr kräftig, auch bei niedrigen Tönen. Die Taste ist direkt an den INT2-Pin angeschlossen, der Pull-Up-Widerstand wird per Software eingeschaltet.

2.3 Takt

Der Quarz taktet den ATmega8515 mit 4,194304 MHz, was exakt auf eine 8-Bit-PWM mit 512 Farbstufen passt (siehe weiter unten).

Quarzfrequenzen Takt Es gehen aber auch andere Quarze noch, und ebenso exakt. Schon der 2,097 MHz-Quarz bringt genug Speed, um die PWM korrekt aussteuern zu können. Das ist das Ergebnis einer ersten Code-Optimierung: wenn die Minute wechselt, brauchte der Code zu lange für 2,097 MHz. Das ist in dieser Version behoben, sodass auch diese Taktfrequenz noch bequem geht. Für die Optimierung war es 6uuml;brigens nötig, den gesamten Zeitbedarf mit allen Taktzyklen festzustellen, wie es in der Software-Sektion gezeigt wird.

Wird stattdessen ein 4 MHz-Quarz verwendet, geht die Uhr pro Minute mit drei Sekunden nach, eine akzeptable Lösung für eine Eieruhr. Gibt man der Software die 4.000.000 in der Konstanten clock an, beträgt die Differenz nur noch 0,03 Sekunden pro Minute, weil dann der CTC-Teiler automatisch einen Teil der Abweichung kompensiert. Alle Quarze und ihre Eignung sind im Libre-Office-Tabellenblatt Quarze hier untersucht und ihre Abweichungen von den 60 Sekunden pro Minute gerechnet. Genauigkeitsfanatiker bleiben beim Quarz 4,194304 MHz.

Interne RC-Oszillatoren Wer es ungenauer mag und vielleicht Quarze für Teufelszeug hält, schaltet den Quarz ab oder montiert ihn gar nicht erst. Er verwendet dann den Internen RC-Oszillator. Der lässt sich auf 1, 2, 4 oder 8 MHz einstellen.

Bei 1 MHz ist nicht genug Zeit, um einen Minutenwechsel in der Interrupt-Service-Routine zu vollziehen. Bei 2, 4 und 8 MHz geht das einwandfrei. Die Differenzen zum exakten Timing sind für eine 11-Minuten-Eieruhr auch hinnehmbar und nur von akademischer Natur. Natürlich muss man die Fuses entsprechend √©instellen und im Quellcode die Konstante clock ändern.

Wer seine Batterie unbedingt mit 8 MHz Takt quälen will, muss auch noch den Prescaler auf 8 einstellen. Die Lösung ist daher in der Tabelle nicht aufgeführt.

2.4 ISP6-Schnittstelle

Nicht im Schaltbild eingezeichnet ist ein Sechs-Pin-Stecker, der der Programmierung des ATmega8515 in der fertigen Schaltung dient. Die Anschlüsse MOSI, MISO, SCK und RESET vertragen sich mit der restlichen Peripherie.

2.5 Widerstände

Die Widerstände Rblau, Rgrün und Rrot sind folgendermaßen zu bemessen:
  1. Maximal sind zwölf Einzel-LEDs gleichzeitig eingeschaltet: in der elften Minute zehn rote (wenn die Option mit Löschen nicht gewählt ist) sowie die beiden in der 11ten LED, die gerade aktiv sind. Die beiden letzten sind zwar nur zu Beginn des PWM-Zyklus beide an, aber so ein Mikrocontroller spürt das.
  2. Der ATmega8515 kann maximal 200 mA über seinen VCC- oder GDN-Pin max. treiben. Daher ist der LED-Strom auf 200 / 12 = 16,7 mA zu begrenzen.
  3. Um noch genug Reserve für den ATmega8515 selbst sowie für den kräftigen Lautsprecherton zu lassen, wurden 15 mA LED-Strom festgelegt, was genügend helle LEDs zur Folge hat.
  4. Bei 15 mA betragen die Durchlassspannungen der Dioden (jeweils mit Exemplarschwankungen) Die Messungen am gebauten Exemplar ergaben etwas andere Werte (siehe das Blatt gemessen in der LibreOffice- Dateil hier.
  5. Bei 15 mA ist die Ausgangsspannung der ATmega8515 Portpins in Sink-Schaltung ca. 0,4 V. Faktisch wurde eine Spannung von 358 mV gemessen, mit Schwankungen zwischen 319 und 410 mV.
  6. Die Widerstände ergeben sich zu
    RLED = (VBetrieb - VLED - VSink) / ILED
  7. Ich habe die nähesten Werte der Reihe E24 gewählt (siehe Blätter widerstand und widerstandsreihen im LibreOffice-Dokument), die käuflich sind.
Das LibrOffice-Dokument zeigt ferner, dass beim Betrieb mit der nächsthöheren Betriebsspannung keine Gefahr besteht, Leuchtdioden zu beschädigen.
Widerstaende bei verschiedenen Betriebsspannungen Die Tabelle zeigt die Widerstandswerte für die drei üblichen Betriebsspannungen
  1. 3,7 V, was das Minimum darstellt und von größeren Li-Zellen geliefert wird,
  2. 4,5 V, das aus drei gestapelten AA- oder AAA-Batterien stammen kann, und
  3. 5,0 V, falls die Schaltung aus einer USB-Buchse oder einer externen Spannungsquelle versorgt werden soll.
Mein eigenes Gerät habe ich mit drei AA-Batterien gebaut und die Widerstände entsprechend dimensioniert. Die gemessenen Spannungen an allen Ausgängen lagen bei 4,2 V Betriebsspannung bei durchschnittlich 0,358 V Sink-Spannung, der durchschnittliche Strom durch die 32 LEDs lag bei 14,19 mA. Die Durchlassspannungen lagen bei den blauen LEDs bei 2,798 V, bei den grünen bei 2,777 V und bei den roten 2,023 V. Der durchschnittliche Strom bei blauen LEDs lag bei 13,11 mA, bei den grünen bei 15,31 mA und bei den roten 14,04 mA. Diese geringen Unterschiede sind optisch nicht wahrnehmbar.

Seitenanfang Eigenschaften Hardware Aufbau Software Fazit

3 Aufbau

3.1 Gedruckte Schaltung

Gedruckte Schaltung fuer die Eieruhr Um das Gerät komfortabel zu bauen, wurde eine einseitig beschichtete gedruckte Schaltung entwickelt. Sie ist auf eine halbe Euro-Platine (100 x 80 mm) dimensioniert.

Komponenten auf der gedruckten Schaltung So sind die Komponenten auf der Platine platziert. Alle Löcher sind 0,8 mm, nur die Anschlüsse für Lautsprecher und Batterie sowie die ISP6-Pins sind 1 mm. Eine Brücke liess sich nicht vermeiden.

Damit der ISP6-Stecker unter den Deckel passt, wurde eine abgewinkelte Steckerversion verwendet.

3.2 Fertigstellung

Nach Bestückung können die Komponenten getestet werden, wofür ein Testprogramm entwickelt wurde (siehe Kapitel Software).

Draufsicht Draufsicht Die gedruckte Schaltung kriegt einen Deckel aus Plexiglas, mit passenden Löchern für die LEDs, den Schalter und die Taste. Genau genommen habe ich den Deckel zuerst gebohrt und dann die LEDs eingelötet, damit alles genau passt. Der Deckel wird mit Abstandshaltern auf Distanz gehalten.

Side view Das ist der Blick von der Seite. Die unterste Ebene besteht aus einer Plexiglasplatte, auf dem der Batteriehalter und der Lautsprecher montiert ist. Der Lautsprecher kriegt kleine 3 mm-Löcher für den Schallaustritt nach unten und ist mit Alleskleber aufgeklebt. Der Abstand zwischen der Platte und der gedruckten Schaltung ist 25 mm.


Seitenanfang Eigenschaften Hardware Aufbau Software Fazit

4 Software

4.1 Downloads

Die Software ist verfügbar im Assembler-Quellcode-Format hier oder kann im Browser hier angesehen werden.

Zum separaten Testen aller Komponenten auf dem Board habe ich den Quellcode hier geschrieben. Siehe hierzu Kapitel 4.4 für Details.

4.2 Assemblieren

Vor dem Assemblieren ist sicherzustellen, dass die korrekten Einstellungen im Quellcode ausgewählt sind. Die voreingestellte Taktrate ist 4,194304 MHz. Ich übernehme keinerlei Verantwortung für Eier, die mit der Default-Taktrate von 1 MHz gekocht wurden und daher vier mal so lang im kochenden Wasser blieben, nur weil Du vergessen hast, per Fuse den externen Quarz als Taktgeber einzuschalten oder weil Du die Konstante clock im Quellcode nicht korrekt angepasst hast.

Für Simulationen habe ich im Quellcode einige Schalter eingebaut, die den Ablauf beschleunigen. Stelle sicher, dass alle diese Schalter auf Null stehen, bevor Du die finale Variante assemblierst.

4.3 Fuses

Fuses des ATmega8515 Vor oder nach dem Programmieren des Flashs sind noch die Fuses des ATmega8515 auf den externen Quarz umzustellen. Danach läuft er mit 4,194304 MHz.

4.4 Hardwarediagnose

Zum Testen der Hardware der Eieruhr habe ich eine Vielzahl von Testroutinen für die Hardwarekomponenten geschrieben. Der Assembler-Quellcode ist hier. Die Datei muss editiert werden, um die Testroutinen auszuwählen, dann assembliert und der Hexcode in das Flash gebrannt werden.

Die folgenden Testroutinen können eingestellt werden:
  1. Port I/O test: testet den Lautsprecher-Ausgang mit SBI- und CBI-Instruktionen,
  2. Timer 1 IO: testet den Lautsprecher via OC1B-Torkeln von Timer TC1,
  3. Led: Schaltet die LED auf weiß, indem alle drei Farben eingeschaltet werden, die LED wird mit der Konstanten dbgLedNr zwischen 1 und 11 eingestellt,
  4. LedRot: rotiert alle 11 LEDs durch Einschalten der blauen, dann grünen und danach der roten LED,
  5. LedPwm: mischt die Farbe der LED mit der Nummer dbgLedNmbr (1..11) aus dem Blauanteil in der Konstanten dbgPwmBlue (0 ... 255), dem Grünanteil in der Konstanten dbgPwmGreen und dem Rotanteil in der Konstanten dbgPwmRed zusammen, eine Verzögerung in der Konstanten delay (zwischen 0 und 255) reduziert die Ausgabegeschwindigkeit (PWM-Frequenz),
  6. Key: wenn die Taste nicht gedrückt ist, ist LED1 blau, wenn gedrückt grün,
  7. Key toggle: schaltet bei jedem Tastendruck die Farbe bzw. die nächste LED ein, so dass Tastenprellen abgelesen werden kann.
Alle Routinen können aktiviert werden, indem die entsprechenden Konstanten auf 1 gesetzt werden. Nur die erste der gesetzten Routinen wird ausgeführt.

4.5 Wie die PWM arbeitet

Zu der Eieruhr-Software zunächst generell: alle Funktionen wie
  1. die LED-PWM,
  2. die Tasteninterrupts, und
  3. der Start und das Anhalten von Tönen,
werden innerhalb von Interrupt-Service-Routinen erledigt. Außerhalb dieser ISRs gibt es nichts zu erledigen, daher kann auf ein Sichern und Wiederherstellen des SREG verzichtet werden.

4.5.1 Timing der PWM

Des Weiteren: Du wirst vergeblich nach Sekunden- und Minutenzählern suchen. Die Software funktioniert aber anders. Das ist deshalb so, weil sich aus einem 4,194304 MHz-Takt keine Sekunde machen lässt. Diue Zeitzähler sind folgendermaßen aufgebaut:
  1. 240 (CTC-Teiler TC0) * 512 (Farben) * 256 (PWM-Zyklen-Schritte) * 8 (PWM-Wiederholungen pro Farbe) ergibt genau 251,658,240 Taktzyklen, bei einem Takt von 4,194304 MHz exakt 60 Sekunden lang.
  2. Der CTC-Teiler von 240 (Compare A = 239) passt das gesamte Timing der Uhr an die Taktfrequenz an. Es muss daher nur diese eine Konstante geändert werden, wenn eine andere Taktfrequenz zum Einsatz kommt.
  3. Die Farben müssen von 0 bis 511 zählen, aufgeteilt in zwei Phasen zu jeweils 256 Schritten.
  4. Der PWM-Schrittzähler zählt nur von 0 bis 0 (=256) und schaltet LED-Farben zu vorgewählten Zeitpunkten aus.
  5. Der PWM-Wiederholzähler zählt nur von 8 an aus abwärts und, wenn nicht Null, startet den nächsten PWM-Durchlauf mit der gleichen Farbkombination, bzw., wenn Null, die nächste Farbkombination.
Es macht daher keinen Sinn in der Software nach einem Sekundenzähler zu suchen: sie hat keinen, und wenn, dann wäre er ziemlich krumm und alles andere als eine Ganzzahl. Er ist auf die 60 Sekunden einer vollen Minute hin ausgelegt, nicht auf eine Sekunde.

Das Timing der Eieruhr funktioniert so:
  1. Die Taktfrequenz von 4,194304 MHz taktet den TC0 mit einem Vorteiler von 1.
  2. TC0 arbeitet im CTC-Modus, mit einem Compare-A-Wert von 239. Das teilt die Taktfreuenz durch 240 und löst mit einer Frequenz von 17.476,26 Hz, alle 57,22046 µs, einen Compare-A-Interrupt aus.
  3. Der TC0-Interrupt gibt den Zustand aller 32 LED-Bits aus, erhöht den PWM-Wert im Register rPwm und prüft anschließend, ob die derzeit aktiven blauen, (im Register rBlue), grünen (im Register rGreen) oder roten (im Register rRed den Vergleichswert in rPwm erreicht haben. Falls das der Fall ist wird das entsprechende von den 32 Bits gelöscht, aber erst beim nächsten TC0-Interrupt an den vier Ports ausgegeben.
  4. Bei jedem 256-sten Mal erreicht rPwm beim Erhöhen Null. In diesem Fall erfolgt kein Vergleich. Alle Farben, deren Anteil im Vergleichsregister bei Null liegt, werden zu Beginn des PWM-Zyklus gar nicht erst eingeschaltet und müssen daher auch nicht ausgeschaltet werden. Dieser Anfangszustand zu Beginn des PWM-Zyklusses ist in den Registern R3:R2:R1:R0 gespeichert und überschreibt beim PWM-Zyklus-Start die Ausgaberegister R7:R6:R5:R4 und startet damit beim nächsten CTC-Interrupt denselben PWM-Zyklus nochmals von vorne. Der Neustart erfolgt acht Mal. Dann ist die nächste Farbe dran. Jeder PWM-Zyklus benötigt 256*57,22046 µs = 14,648 ms. Das entspricht eine PWM-Frequenz der LEDs von 1.000 / 14,648 = 68,267 Hz. Acht Durchläufe benötigen 117,188 ms.
  5. Sind acht PWM-Zyklen absolviert, dann ist die nächste Farbe dran. In der Farbphase 1 wird dazu der grüne Wert in rBlue um Eins vermindert und der blaue Wert in rBlue um Eins erhöht. Das macht 256 urchläufe in dieser Phase, dann erreichen beide Register wieder Null. Diese Phase dauert 256 * 117,188 ms = 30 Sekunden.
  6. In der Farbphase 2 nimmt der Blauanteil ab und der Rotanteil zu. Auch diese Phase dauert 30 Sekunden. Ist diese absolviert dann ist die n&aum;chste LED dran.
Das wiederholt sich elf Mal, wobei die elfte LED keinen Blau-Anschluss hat und nur Grün und Rot aktiv sind.

4.5.2 Organisation der PWM-LED-Bits

Die nachfolgend beschriebene Organisation der PWM-Bits der 32 LEDs optimiert den Aufbau und Ablauf der Software.

Die 32 LEDs (10 * 3 + 2) sind an den Portbits angeschlossen wie in der Grafikare gezeigt. Während der PWM-Zyklen werden eingeschaltete LEDs mit einer Eins, ausgeschaltete mit einer Null belegt. Diese Bits schalten die Richtungstreiber DDcn an und aus. Das ermöglicht den Betrieb mit gemeinsamer Anode (PORTcn = 0) ebenso wie mit gemeinsamer Kathode (PORTcn = 1).

I/O-Port- und Register-Organisation Diese Organisation der Register wurde gewählt, damit man nicht für jede der 11 LEDs eigene Routinen schreiben musste. Da jeweils drei Farben pro LED anzusteuern sind, liegen die Farben B, G und R jeweils an spezifischen Orten im Byte, teils überlappend.

Für den Betrieb der PWMs sind zwei Registersätze nötig:
  1. R3:R2:R1:R0 speichert den Zustand der PWM-Ausgänge zu Beginn jedes PWM-Zyklusses. Das ist nötig, da jede Farbkombination acht Mal abgearbeitet werden muss. Diese vier Register überschreiben den Wert der vier Ausgaberegister mit jedem PWM-Zyklusstart. Zu Beginn der Minute ist nur die grüne LED eingeschaltet, die blaue und rote wird erst hinzu eingeschaltet wenn deren Wert in rBlue bzw. rRed mindestens Eins ist.
  2. R7:R6:R5:R4 enthält den Zustand im Laufe des PWM-Zyklusses. Die jeweilige blaue, grüne bzw. rote LED werden darin ausgeschaltet, wenn ihr Vergleichswert erreicht wird. hold the current condition at each PWM step. Diese vier Register werden an die Richtungsports der vier LED-Ports ausgegeben.

4.5.3 CTC-Zugriff auf die PWM-LED-Bits

Fliessdiagramm normaler PWM-Schritt Der Zugriff auf die einzelnen Farbbits der 11 LEDs erfolgt etwas eigenartig, damit das Schreiben von 11 Routinen vermieden werden kann.

Der Zugriff erfolgt mit zwei Zeigern:
  1. Das Doppelregister YH:YL zeigt auf dasjenige Register, in dem sich die blaue LED der aktuellen Minute befindet. Zu Beginn zeigt Y auf Null. Mit entsprechendem Zeitfortschritt zeigt es auf 1, 2 oder 3.
  2. Das Register rBB enthält eine binäre Eins an derjenigen Stelle, an der sich die blaue LED der aktuellen Minute befindet und ist ansonsten Null. rBB wird dreifach nach links verschoben, wenn die nächste LED angesteuert werden soll (z. B. wenn eine Minute um ist). Immer dann, wenn beim Linksschieben eine Eins im Carry landet, muss
Der Quellcode für dre mal links schieben sieht dann so aus:

  lsl rBB ; Einmal links schieben
  brcc CNoBlue ; Kein Carry
  inc YL ; Zeiger auf naechstes Byte
  rol rBB ; Carry in Bit 0
CNoBlue:
  lsl rBB ; Zweites Mal links schieben
  brcc CNoGreen ; Kein Carry
  inc YL ; Zeiger auf naechstes Byte
  rol rBB ; Carry in Bit 0
CNoGreen:
  lsl rBB ; Drittes Mal links schieben
  brcc CNoRed ; Kein Carry
  inc YL ; Zeiger auf naechstes Byte
  rol rBB ; Carry in Bit 0
CNoRed:

Auf diese Weise sind alle Bits zugänglich. Es ist nur sicherzustellen, dass beide Zeiger immer auf die aktuelle blaue Minuten-LED zeigen. Die beiden Zeiger ersetzen also Sekunden- und Minuten-Zähl-Register.

Das Setzen des aktuellen blauen Bits auf Eins im PWM-Startregister-Satz geht dann so:

  ld r,Y ; Lese Inhalt des Registers mit dem aktuellen blauen Bit
  or r,rBB ; OR mit dem aktuellen blauen Bit
  st Y,r ; Zuruekschreiben des Ergebnisses in das blaue Register

Soll das akuelle blaue Bit im Arbeits-Register-Satz ausgeschaltet werden (z. B. wenn Gleichheit mit dem rPwm-Wert erreicht wird), geht das so:

  ldd r,Y+4 ; Lese Inhalt des blauen Arbeitsregisters (4 Byte Versatz)
  eor r,rBB ; EXOR mit dem blauen Bit
  std Y+4,r ; Zurueckschreiben in das blaue Arbeitsregister

Mit LDD kann Y nicht nur auf die vier untersten Byte zugreifen sondern auch auf die genau vier Byte höhere Adresse im Arbeitsregister. Der Unterschied zwischen LD und LDD ist kaum merklich, LDD braucht genausoviel Taktzyklen wie LD auch (zwei).

Die Interrupt-Service-Routine kann je nach den anstehenden Aufgaben länglich sein. Daher wurde entschieden, die Ausgabe an den Beginn zu legen, dann erfolgt sie immer zum gleichen Zeitpunkt und ist unabhängig davon, wie lange Verzweigungen andauern. Außerdem ist sicherzustellen, dass alle Verzweigungen nicht länger als 240 Taktzyklen benötigen, weil sonst die Gefahr besteht, dass der CTC-Interrupt verpasst würde.

Die Software verbringt 89% der Zeit im Sleep-Modus, es ist daher sinnvoll, diesen Modus zum Batteriesparen einzuschalten.

4.5.4 Ein normaler CTC-PWM-Zyklus: Farbvergleich

So (siehe rechts) sieht ein normaler PWM-Schritt aus. Es beginnt mit der Ausgabe der vier Register auf die vier Richtungs-Ports. Dann wird der PWM-Zyklus-Zähler rPwm erhöht. Wenn dieser Null erreicht, geht es mit einer anderen Routine weiter (siehe unten). Ist das nicht der Fall, werden nacheinander die drei Farben überprüft. Bei blau geht das mit den aktuellen Zeigern Y und rBB. Bei grün muss der Zeiger einmal links geschoben werden, bei der roten zwei Mal. Zum Ende muss der Zeiger wieder auf blau zeigen, also zwei Mal rechts geschoben werden.

Im Flussdiagramm wurden die Anzahl Taktimpulse hinzugefügt. Insgesamt würden 57 Taktzyklen benötigt, wenn alle Schiebereien mit gesetzten Carry-Bits laufen würden. Minimal dauert es 41 Taktzyklen, wenn keine LED zu schalten ist und kein Carry auftritt. Das entspricht zwischen 17 und 24% der verfügbaren Takte bis zum nächsten CTC-Interrupts.

4.5.5 Wiederholungen des PWM-Zyklus

PWM-Wiederholung Wie oben beschrieben wird der PWM-Zyklus acht Mal wiederholt. Dieser Teil der CTC-ISR erledigt das. Sie zählt den Zähler abwärts, ist er nicht Null, werden die vier Startwerte über die Arbeitsregister kopiert. Wenn der nächste CTC-Interrupt zuschlägt, wird diese Kombination an die Ports ausgegeben. Ist der Zähler Null, ist die nächste Farbkombination dran, siehe unten.

Der Widerholungsteil ist kürzer als der Vergleichsteil. Aber da dieser nur bei jedem 256sten Durchlauf bearbeitet wird, macht dieser kurze Teil nicht viel am gesamten Zeitablauf aus.

4.5.6 Die nächste Farbe

Fliessdiagramm naechste Farbe Sind acht PWM-Zyklen mit denselben Blau-, Grün- und Rot-Werten durchlaufen, dann sind sowohl rPwm als auch rPCnt bei Null. Daher wird rPCnt wieder mit 8 neu gestartet. Ist gerade die Stop-Flagge gesetzt und die Uhr angehalten, wird einfach der Anfangszustand geschrieben.

Ist die Stop-Flagge nicht aktiv, kommt die nächste Farbe dran. Das bedeutet, dass abhängig von der Farbphase
  1. in Phase 1 der Grünanteil um Eins vermindert und der Blauanteil um Eins erhöht wird, oder
  2. in Phase 2 der Blauanteil um Eins vermindert und der Rot-Anteil um Eins erhöht wird.
In beiden Fällen ist die entsprechende neue Farbe (blau in Phase 1, rot in Phase 2) im PWM-Start-Register einzuschalten. Das macht man mit einem binären ODER von rBB an der Adresse Y (blau) bzw. mit dem zweifach links auf rot verschobenen rBB. Natürlich ist beim Linksschieben wieder auf gesetzte Carry-Flaggen zu achten.

Wenn beim Erhöhen bzw. Erniedrigen der Farbwerte Null erreicht wird, wird in Phase 1
  1. die Phasenflagge gesetzt und Phase 2 eingeleitet, und
  2. die grüne LED im Startregister-Set gelöscht, dazu wird rBB einmal links geschoben und das Bit mit EOR ausgeschaltet, und
  3. rBB einmal rechts geschoben und damit wieder auf die blaue LED eingestellt.
In Phase 2 wird beim Erreichen von Null die nächste LED angesteuert (siehe das folgende Kapitel).

Die gesamte Routine braucht zwischen 29 und 50 Takte und ist dauert etwa so lange wie auch der Farbvergleich.

4.5.7 Die nächste LED

Fliessdiagramm naechste LED Wenn der Ablauf in Phase 2 beim Erhöhen/Erniedrigen der Farben eine Null herauskommt, ist eine Minute vorbei und wird die nächste LED angesteuert.

Das Umschalten auf die nächste LED ist am Beispiel des Übergangs von LED3 auf LED4 gezeigt. KED3 befindet sich mit der blauen und grünen LED in der linken Seite von R0 (bzw. R4) und mit der roten LED im Bit 0 von R1 (bzw. R5). Beispiel naechste LED Die Schritte sind folgende:
  1. zuerst wird die Phase-2-Flagge gelöscht, da es jetzt wieder mit Phase 1 weitergeht,
  2. dann wird die aktuelle blaue LED im Startregister-Set gelöscht, die rote LED wird nicht gelöscht und bleibt an (sie wird erst beim nöchsten LED-Zyklus gelöscht),
  3. dann wird geprüft, ob die letzte LED, LED11, aktiv ist. Das ist der Fall, wenn Wenn beides der Fall ist, wird die Uhr abgeschaltet, was folgendes zur Folge hat:
  4. Wenn Y=3 ist und die LED10 aktiv ist (rBB ist bei 8 bzw. hat Bit 3 gesetzt), dann Dann springt dieser Zweig zu der Routine mit dem Kopieren des Startregister-Sets über den Arbeitsregister-Set.
  5. Wenn Y=3 ist und weder LED10 und LED11 aktiv ist, wird die nächste grüne LED direkt aktiviert. Dazu wird rBB vier Mal links geschoben, das gr&uul;ne Bit aktiviert und die Kopierroutine absolviert.
  6. Derselbe Ablauf mit vier Mal links schieben und grün anschalten wird auch dann absolviert, wenn entweder In beiden Fällen wird die vergangene rote LED nicht ausgeschaltet und direkt zum Setzen der nächsten grünen LED verzweigt.
  7. Wenn Y nicht 3 ist, wenn das Löschen nicht ausgeschaltet ist und wenn LED1 nicht aktiv ist, dann wird durch Rechtsschieben von rBB das rote Bit der vorherigen LED angesteuert und mit EOR ausgeschaltet. Danach wird rBB um fünf Stellen nach links geschoben (jeweils mit Carry-Prüfung) und die grüne LED einschaltet.
  8. rBB wird nach dem Anschalten der grünen LED um eine Stelle nach rechts auf die blaue LED geschoben. Dann werden die Einstellungen im Startregister-Set über die Arbeitsregister kopiert und die Routine mit RET beendet.
Die gesamte Routine benötigt je nach den Verzweigungen zwischen 48 und 97 Taktzyklen. Da sie nur einmal pro Minute ausgeführt wird, spielt sie keine Rolle für den Gesamtstrombedarf. Die 97 Taktzyklen begrenzen allerdings die Mindest-Taktrate des Prozessors. Die Default-Rate mit 1 MHz Takt reicht dafür nicht aus. Es könnte trotzdem funmktionieren, da der nächste CTC-Int kürzer ist und nur der Schreibtakt des ersten CTC nach der LED-Umschaltung etwas verspätet beginnt.

4.5.8 Gemeinsame-Kathoden-LEDs?

Die gesamte Software kann so bleiben wie sie ist, wenn LEDs mit gemeinsamer Kathode verwendet werden sollen. Dazu müssen zu Beginn alle Portregister PORTcn (mit c = A..D und n = 0..7) auf Eins gesetzt werden. Die internen Pull-Ups, die mit dieser Einstellung eingeschaltet werden, wenn DDcn auf Null steht, machen nichts aus, da sie nur maximal 60 µA durch die LEDs fliessen lassen. Das ist zu wenig, um sichtbar zu sein.

Natürlich muss die Hardware dann anders aussehen: alle mit Plus verbundenen Anoden müssen als Kathode an Minus und die gedruckte Schaltung entsprechend ge&aum;ndert werden.

Seitenanfang Eigenschaften Hardware Aufbau Software Fazit

4.6 Wie die Sound-Ausgabe funktioniert

4.6.1 TC1 als Tongenerator

Um Töne zu erzeugen, wird TC1 im CTC-Mode betrieben, mit dem Compare-A-Portregister als Rücksetzwert. Compare B wird auf Null oder 1 gesetzt und schaltet den OC1B-Ausgang: ist der Ton angeschaltet, dann wird dieser auf Torkeln eingestellt, ist er aus, dann wird er auf Clear geschaltet.

Die Zeitdauer, über die der Ton angeschaltet bleibt, wird im Registerpaar R25:R24 eingestellt. Dieses wird mit 16 Bits dekrementiert. Erreicht es Null, dann wird
  1. die Flagge bSound gelöscht, und
  2. der OC1B-Pin auf Clear gesetzt.
Der Compare-Match-Interrupt bleibt aktiv, allerdings schaltet die Flagge auf eine andere Betriebsart um (siehe unten).

Beim höchsten Ton, a6 mit 14,080 kHz, beläuft sich die maximale Tondauer auf 2.3 s, beim niedrigsten, A1minor mit 55 Hz, kann der Ton bis zu 596 s andauern.

4.6.2 Die Tonleitertabelle

Um angenehme Töne zu produzieren, ist eine Tonleiter in die Software integriert. Die Tonleitertabelle GamutTable: besteht aus zwei Worten für jeden Ton. Das erste Wort gibt den CTC-Teilerwert mit dem MSB zuerst an (da das MSB als erstes in OCR1AH geschrieben werden muss). Das zweite Wort gibt den Zälwert an, für den der Ton anbleiben muss, um eine Sekunde lang zu dauern, was die Frequenz mal zwei ist.

Alle Oktaven von A1minor über Aminor und a0 bis g7 sind in der Tabelle enthalten.

Im Quellcode bestimmt die Konstante cOctave, aus welcher Oktave die auszugebenden Töne stammen sollen. Sie kann zwischen -2 und +6 eingestellt werden. -2 startet mit A1minor oder 55 Hz. Jede Minute wird ein Ton höher ausgegeben, -2 erstreckt sich daher bis zum Ton e (165 Hz). -1 beginnt mit Aminor mit 110 Hz und geht bis e1 (330 Hz). a2 als Startwert mit 880 Hz ist die Default-Einstellung (cOctave=2).

Das Registerpaar ZH:ZL zeigt jeweils auf die aktuelle Tonleiter-Position in der Tabelle. Wenn die Flagge bPlay gesetzt ist, beginnt die Tonausgabe an dieser aktuellen Position.

Die Tonleiter-Tabelle ist im Blatt sound in der LibreOffice-Tabelle hier zugänglich. Durch Markieren und Kopieren der Spalte Assembler-Quellcode kann der Quellcode der Tabelle in den Quellcode übernommen werden. Da die Tabelle mit der Taktrate 4,194304 MHz erstellt wurde, ist sie bei einer anderen Taktrate entsprechend umzurechnen und zu überschreiben.

4.6.3 TC1 als Soundchecker

Wenn kein Ton aktiv ist, dient TC1 als Erkenner für gesetzte bPlay-Flaggen. Dazu ist alle 1 ms der CTC-Interrupt aktiv, der für eine voreingestellte Zeit lang abwärts zählt. Ist er Null, wird die Flagge bPlay abgefragt. Ist diese gesetzt, wird die Tonausgabe gestartet.

Ist der Ton zu Ende gespielt, wird dieser Modus durch Löschen der Flagge bSound wieder eingestellt.

5 Fazit

Dieses Projekt zeigt, dass Das zeigt ferner die sehr klaren und eleganten Möglichkeiten der Assembler-Programmierung auf. Keine andere Programmiersprache eröffnet solche Möglichkeiten für exaktes Timing. Versuche das insbesondere nicht mit C, Du kriegst nur graue Haare davon.

Seitenanfang Eigenschaften Hardware Aufbau Software Fazit


Lob, Tadel, Fehlermeldungen, Genöle und Geschimpfe oder Spam bitte über das
Kommentarformular an mich.

©2019 by http://www.avr-asm-tutorial.net