Pfad: Home => AVR-DE => Anwendungen => Groß-Uhr m48
Großuhr-7-Segment-Anzeige AVR-Anwendungen

Groß-Uhr mit ATmega48
Hardware, Aufbau, Anwendung und Software für die Groß-Uhr
Logo

Groß-Uhr mit ATmega48

Großuhr ATmega48
  1. Eigenschaften
  2. Hardware
  3. Aufbau
  4. Software
Diese Seiten als PDF (36 Seiten, 547 KB).

1 Eigenschaften der Groß-Uhr mit ATmega48

Die Hardware-Eigenschaften der beschriebenen Groß-Uhr:

Seitenanfang Eigenschaften Hardware Aufbau Software

2 Hardware

2.0 Vorbemerkungen

Bei der Entwicklung der Hardware dieser Uhr habe ich folgende Erfahrungen gesammelt, die vielleicht für andere hilfreich sein könnten:
  1. Mein erster Versuch, den Prozessor direkt mit einem Uhrenquarz mit 32,768 kHz zu takten, erwies sich als nicht realisierbar. Nicht dass das nicht gehen täte. Man muss dazu natürlich die Fuse auf einen externen Quarz und nicht auf einen externen Quarzoszillator einstellen (Fehler #1). Das Studio 4.19 hat diese fehlerhafte Umstellung übrigens gar nicht bemerkt und alles als ok verifiziert. Erst als ich über ISP nochmals auf die Fuses zugreifen wollte, kam die Fehlermeldung. Als der Fehler dann mit Hilfe der Hochvolt-Parallelprogrammierung im STK500 behoben war, ging es aber trotzdem nicht. Der Chip war über HV sehr wohl, aber über ISP in der Uhrenschaltung gar nicht ansprechbar. Nur wenn ich die Betriebsspannung in der Zielplatine der Uhr auf 5 V erhöhte (natürlich ohne angeschlossenes Display), lief die Blinkroutine ordnungsgemä ab. Ursache war aber nicht, dass der Prozessor nicht mit 32,768-kHz-Quarzen klar kommt, sondern dass der Brown-Out-Detektor in der Einstellung 2,7 V nicht wirklich bei 2,7 V auslöste sondern noch weit darüber bei 4 V anspricht und den Chip dauerhaft rücksetzte. Erst nach dem Abschalten der Brown-Out-Detektion lief alles stabil (Fehler #2). Aber noch nicht genug damit: das Studio 4.19 weigert sich beharrlich, mit 4 kHz ISP-Frequenz zu programmieren. Es behauptet, das sei unter 5 kHz nicht möglich, obwohl das Handbuch des ATmega48 keinerlei Hinweis auf eine solche Beschränkung enthält und das Original-STK500-Protokoll noch viel niedrigere Programmiergeschwindigkeiten ohne Probleme beherrscht (Fehler #3). Es muss sich daher um einen Fehler beim Implementieren der Flash-Programmierung im Studio handeln. Da bei Prototypen die Entwicklung etwas komplizierterer Programme ohne ISP-Programmierung eine Quälerei ist, habe ich das Vorhaben mit 32,768 kHz Taktfrequenz schließlich schweren Herzens aufgegeben. Obwohl ich schon gerne wüsste, ob ich das alles zeitlich korrekt hingekriegt hätte (ich vermute: ja - 32.768 Instruktionen in der Sekunde sind in Assembler halt doch noch viel Holz).
  2. Da ich geplant hatte, auf die 16 Dioden zu verzichten, die acht Konstantstromregler mit Transistoren normalerweise brauchen, habe ich die Betriebsspannung des Prozessors so weit herabgesetzt, dass die Dioden nicht gebraucht werden und die Regeltransistoren mit der Basis direkt auf Portspannungsniveau hängen. Nach meiner Rechnung war dafür 3,3 V Betriebsspannung ideal, um mit einem Emitterwiderstand von 100Ω auf 27 mA Konstantstrom zu kommen. Leider ergab schon der erste Versuch, dass der Spannungsregler BA033FB stolze 4,04 V abgab. Mit den sich daraus ergebenden (4,04 - 0,6) / 100 * 1000 = 34,6 mA wären die Leds einen schnellen Tod gestorben (Fehler #4) und der Trafo wäre mit 277 mA in den Kurzschlussmodus übergegangen. Es blieb nichts anderes über als ein ordentliches 3,3 V-Netzteil zu Fuß und ohne fertigen (falschen Regler) selbst zu bauen.
  3. Der vom Versandhändler gelieferte 2,8VA-Trafo erwies sich als viel zu schwach und hat nach Gleichrichtung bei Belastung mit 82Ω (198 mA) nicht mehr seine Nominalspannung abgeliefert (Fehler #5). Er hatte auch nicht 12 V nominal sondern 15 V (Fehler #6). Und das erklärt, warum er bei 82Ω Last schon zusammenbrach (2,8VA / 15V = 187mA). Die höhere Spannung brachte den Ladeelko fast zum Aufblähen seiner Backen (zu hohe Überspannung bei Nulllast, war nur durch den Einbau einer Betriebsspannungs-Led zu beheben) sondern auch das 27mA-Konzept zum Scheitern, denn bei allen acht Segmenten angeschaltet wären mit 216 mA der Trafo und das Netzteil überfordert gewesen. Es blieb daher nur, auf die minimalen 2,7V Betriebsspannung des ATmega48 und auf ca. 19 mA Konstantstrom zu gehen. Der Helligkeitsunterschied erwies sich allerdings als kaum merklich, deshalb war der Kompromiss noch erträglich.
  4. Normalerweise reichen beim Multiplexen von vier Ziffern 50 bis 60 Hz vollkommen aus und man erkennt kein Flimmern mehr. Bei Versuchen mit dem großen Display stellte sich aber heraus, dass 60 Hz doch noch unangenehm flimmern (Fehler #7). Das Konzept musste daher auf 100 Hz und mehr umgestellt werden.
Ich finde sieben Fehler einfach zu viel, von denen sechs von mir nicht zu vertreten waren. So macht Basteln keinen Spaß mehr.

2.1 Anzeigen-Teil

Schaltbild einer Displayziffer Dies ist eine der vier Ziffern der Anzeige der Uhr. Sie besteht aus 28 10mm-Leds, jeweils pro Segment vier hintereinandergeschaltet. Alle Anoden einer Ziffer (A) werden verbunden und als A1..A4 über Flachkabel an eine 16-polige Buchse geführt.

Die Kathoden a bis g werden über alle vier Ziffern zusammen verbunden und ebenfalls an die 16-polige Buchse geführt.

Die zwei blinkenden LEDs in der Mitte bilden das achte Segment. Dessen Anode kann an eine der vier Ziffern angeschlossen werden. Welche das ist muss per Software eingestellt werden.

Die Belegung der 16-poligen Buchse ist im Schaltbild der Prozessor- und Treibereinheit dokumentiert.

2.2 Prozessorteil

2.2.1 Auswahl des AVR-Typs

Auswahl des AVR-Typs Der AVR-Typ ergibt sich aus folgenden Hardware-Anforderungen:
  1. Da die Uhr auch ohne DCF77-Synchronisation über längere Zeit ziemlich genau laufen soll, muss entweder der Prozessor mit einem externen Quarz getaktet werden oder der Timer/Counter TC2 muss mit einem externen Uhrenquarz laufen.
  2. Damit auf eine dauernde Abfrage des DCF77-Eingangs und der beiden Taster-Eingänge verzichtet werden kann, sollten Flanken an diesen drei Eingängen mit einem INTn oder PCINTn zu Interrupts führen.
  3. Die acht Konstantstrom-Schalter sollten in einem Port, vier weitere Anodenschalter in einem weiteren Port liegen.
  4. Die Messung des Potentiometer- und des Lichtsensor-Eingangs muss in zwei Analog-Eingängen erfolgen.
  5. Für das Multiplexen der Anzeige ist ein 8-Bit-Timer, für die Messung der DCF77-Signaldauer ein 16-Bit-Timer vonnöten.
Durch die Software hier engt sich die Auswahl auf einige wenige AVR-Gruppen ein. Der ATmega48 erfüllt alle genannten Anforderungen. Wer den gerade nicht vorrätig hat, kann auch einen ATmega88 nehmen, der nur ein wenig mehr unnützes Flash-Memory mit sich herumträgt.

2.2.2 Auswahl der Taktfrequenz

Den Takt erhält der ATmega48 aus einem angeschlossenen Quarz mit 4,096 MHz. Die beiden Keramikkondensatoren von 22 pF helfen beim Anschwingen des Quarzoszillators. Die Quarzoszillator-Fuse des ATmega48 ist vom internen RC-Oszillator auf den externen Quarz umzustellen (siehe Fuse-Umstellung), weil sonst die Uhr um den Faktor 1,024 zu langsam geht (35 Sekunden pro Tag).

Die Gründe für die Auswahl dieses Quarzes waren folgende (siehe auch das Tabellenblatt Timer im Open-Office Tabellenwerk hier):
  1. Der Quarz sollte auch im Handel erhältlich sein.
  2. Die Quarzfrequenz, geteilt durch 8 oder 64 sowie durch 256 muss eine Ganzzahl ohne Rest ergeben.
  3. Das Teilen durch 256 ist erforderlich, damit der Multiplextakt durch einen 8-Bit-Timer erfolgen kann, dessen Compare-Register auch das vorzeitige Abschalten der Anodentreiber vornehmen kann (Dimm-Funktion, Wertebereich zum Abschalten 0..255). Wer stattdessen einen Quarz verwendet, der zum Erreichen ganzzahliger Teilerfrequenzen den CTC-Modus erzwingt (z. B. 2,0 oder 4,0 MHz), muss die Abschaltfunktion auf Compare B verlegen und durch Ändern der Multiplikation die Potentiometerwerte zum Dimmen auf diesen Maximalwert im Compare-A-Port begrenzen.
  4. Wählt man als Prescaler 8, dann werden bei der niedrigsten Quarzfrequenz von 2,048 MHz viel zu hohe Multplexfrequenzen erhalten (1000 Hz), was zu unnötigem Stromverbrauch und zu HF-Feldern fürt. Wählt man aber 64, ist die MUX-Frequenz mit 31,25 Hz aber etwas zu niedrig. Es empfehlen sich also Quarze ab 3,2768 MHz aufwärts (MUX-Frequenz 50 Hz und höher).
4,096 MHz erfüllt die Anforderungen, die MUX-Frequenz liegt mit 125 Hz in einem optimalen Bereich.

2.2.4 Schaltbild der Uhr

Schaltbild Prozessor- und Treiberteil Dies ist der Prozessorteil mit dem ATmega48 und allen seinen angeschlossenen Komponenten.

2.2.5 Kathodentreiber als Konstantstromquellen

Der Port D des Prozessors steuert die Kathoden der Anzeige. Die Ausgänge des Ports werden mit 1k-Widerständen an die Basen von NPN-Transistoren BC547 geführt, deren Emitterwiderstände von 100Ω die Segmentströme auf ca. 21 mA begrenzen:
IE = (2,7V - 0,6V) / 100 * 1000 = 21 mA

Die Portausgänge sind aktiv high.

Das ist auch der Grund, warum die Betriebsspannung des AVR bei 2,7 V liegt: bei 5 V wären am Emitterwiderstand schon 4,4 V verbraten worden, was zusammen mit den 4 * 3,18 V = 12,72 V für die vier LEDs und den ca. 0,2 V UCE(sat) des BD440 17,3 V ergäben hätte. Die Konsequenz wäre gewesen, dass ein 12V-Trafo nicht ausreichend gewesen wäre und stattdessen ein 15V-Typ erforderlich gewesen wäre, den es aber in der zweiwickligen Ausführung nicht in der passenden Größe zu kaufen gibt.

Eine Alternative wäre gewesen, die 5 V mit zwei Dioden auf 1,4 V herabzusetzen. Da dazu aber 16 dieser Dioden zu verbauen gewesen wären, wurden 2,7 V Betriebsspannung gewählt.

Ursprünglich hatte ich den Plan, die Uhr mit einem 32kHz-Uhrenquarz zu betreiben. Diesen Plan habe ich wegen unüberwindlichen Schwierigkeiten aufgegeben.

2.2.6 Anodentreiber

Die vier Anoden werden vom unteren Teil von Port B angesteuert. Die unteren drei Bits sind direkt an die Basen von BC547-NPN-Transistoren gefürt, die Durchsteuerung erfolgt mittels den per Software eingeschalteten Pull-Up-Widerständen. Der Strom aus den Pull-Up-Widerständen von ca. 47k reicht aus, um die Transistoren mit einem hFEmin von 150 zu treiben:
IC = (2,7V - 0,7V) / 47kΩ * hFEmin * 1000 = 6,4 mA
Die eingeschalteten NPN-Transistoren schalten über 2k2-Widerstände die Basis der Anodentreibertransistoren BD440 an. Die bei 16V Betriebsspannung fließenden 6,4 mA Basisstrom reichen bei weitem bin, um die BD440-PNPs mit einem hFE schon von ca. 30 mit einem Kollektorstrom von maximal 200 mA voll durchzusteuern.

Da das vierte Anodenbit beim Betrieb der ISP6-Schnittstelle mit dem MOSI-Signal getaktet wird, ist der NPN-Transistor in diesem Fall mit einem 10k-Widerstand angeschlossen und der Portausgang ist als Ausgang konfiguriert.

2.2.7 ISP6-Schnittstelle

Die Portpins PB3 bis PB5 bedienen die ISP6-Schnittstelle, über die der Flashspeicher in der Schaltung mit dem Programmcode gefüttert werden kann. Ist beim Programmieren kein Netzteil angeschlossen, muss das Programmiergerät 3,3 V liefern und entsprechend konfiguriert werden. Sind die LEDs beim Programmieren nicht angeschlossen, können auch 5 V zum Programmieren verwendet werden. Würden die LEDs bei 5 V angeschlossen, läge ihr Strom bei 44 mA, was sie zwar kurzzeitig vertragen, aber nicht für länger. Allerdings würde sich der Strom bei allen acht Kathoden auf 350 mA belaufen, was das Netzteil nicht liefern kann.

2.2.8 Sonstige Peripherie

An Port C ist die restliche Peripherie angeschlossen:
  1. An PC0 (ADC0) ist das Potentiometer angeschlossen und wird im Wechsel mit dem Lichtsensor laufend in einen Binärwert umgewandelt.
  2. An PC1 (ADC1) ist ein Fototransistor zur Messung der Umgebungshelligkeit angeschlossen.
  3. An PC2 ist eine kleine grüne LED angeschlossen. Sie kann als Betriebsspannungs-LED oder im Hardware-Debug-Modus zum Anzeigen von Ereignissen dienen (siehe Hardware-Debugging)
  4. An PC3 und PC4 bzw. den folgenden drei Pins der 10-poligen Steckverbindung sind die beiden Tasten angeschlossen, die durch die Pull-Ups von PC3 und PC4 auf Eins liegen und beim Schließen auf Null gezogen werden (aktiv low).
  5. An PC5 wird das DCF77-Modul angeschlossen. Es ist egal, ob dessen Ausgang aktiv low oder high ist. PC5 hat den Pull-Up ebenfalls gesetzt, so dass bei nicht angeschlossenem Modul keine Störsignale den Programmablauf stören. Das Modul sollte bei 2,7 V Betriebsspannung schon arbeiten.

2.3 Netzteil

Netzteil für die Groß-Uhr Das Netzteil muss folgende Eigenschaften besitzen:
  1. Es muss die mindestens 16 V 0,2A liefern, die für den Betrieb der LEDs erforderlich sind.
  2. Es muss ferner die 2,7 V für den Betrieb des Prozessors liefern. Der Regler muss bis zu 25 V vertragen, die das Netzteil ohne angeschlossene Last im Leerlauf produzieren kann.
Im Schaltbild ist so ein Standard-Netzteil mit einem 2*12 V-Trafo mit seiner Dimensionierung zu sehen. Die beiden Dioden sind 1N4001.

Netzteilspannung ohne Last Das hier simuliert das dargestellte Netzteil ohne angeschlossene Last (siehe die Power-Supply-Software hier). Die Spannung am Elko bleibt ohne Last in der Theorie bei deutlich unter 25 V, deshalb kommen die Elkos mit einer Spannungsbelastbarkeit von 25 V aus. In der Praxis stellte sich allerdings heraus, dass der Trafo den angegebenen Spannungsfaktor bei weitem nicht einhält und fast doppelt so hohe Spulenwiderstände hatte. Im Leerlauf lieferte er daher eine viel höhere Spannung als berechnet. Um den Elko nicht zu gefährden, war es notwendig, die Leerlaufspannung mit der Kombination aus gelber 3mm-LED und 2k7 herabzusetzen, um unter die 25V zu kommen. Verlasse Dich also nie auf Herstellerangaben, in der Regel ist die Realität schlechter.

Der viel höhere Leerlaufspannungsfaktor hatte außerdem zur Folge, dass die Spannung bei einer Last von 200 mA gerade mal nur noch 12,4 V betrug. Da die 200 mA nur auftreten, wenn alle 8 Segmente angeschaltet sind (und das wegen des Multiplexens der Anzeige auch nur für 16 ms lang, also maximal für einen Netzspannungsdurchgang lang), ergeben sich keine nachteiligen Konsequenzen für die Spannung der Anzeige. Was alles so unter dem Siegel "2*12V 2,8 VA" verkauft wird ...

Normalerweise nimmt man für die Regelung der niedrigen Spannung gerne einen integrierten Spannungsregler. Das ergab aber katastrophale Ergebnisse: der integrierte 3,3V-Regler lieferte stolze 4,04V Ausgangsspannung, und das bei immerhin schon 30mA Last. Da das die Anzeigenlampen zerstört hätte, musste eine Lösung mit niedrigerer Spannung her, also 2,7 V. Das ist die Mindestspannung, die der ATmega48 zum Funktionieren seiner Hardware erwartet. Und für 2,7 V gibt es keine integrierten Spannungsregler, die diese Mindestspannung auch garantieren (der 78L02 geht gerne auch mal mit weniger als 2,7V zu Werke, z. B. mit 2,45V).

Die Lösung war, den 2,7 V-Spannungsregler über eine Zenerdiode mit einem NPN-Transistor selbst zu bauen. Damit entgeht man allem Ärger mit den leidigen Bauteiltoleranzen.

Netzteilspannung bei 230 mA Maximallast Das hier ist die berechnete Netzteilspannung bei 230 mA Last, der Maximallast während der höchsten Multiplexphase und mit dem höchsten Prozessorverbrauch. Die Spannung sinkt leicht unter 16 V, aber nur geringfügig, so dass der Betrieb der LEDs nicht gestört wird. Es besteht ausreichend Lastreserve und der Elko ist mit einem Ripple von 1,3 V, das von der Konstantstromregelung der LEDs abgefangen wird, großzügig dimensioniert.

In der Praxis wies der Trafo aber einen viel höheren Leerlauf-Spannungsfaktor auf und lieferte wegen der höheren Spulenverluste auch weniger Strom als die aufgedruckten 117 mA pro Spule. Die Konsequenz war die Herabsetzung des Lampenstroms durch Senkung der Betriebsspannung des ATmega48 und der Einbau der gelben LED, denn im Leerlauf erreichte der Trafo 27 V am Elko.


Seitenanfang Eigenschaften Hardware Aufbau Software

3 Aufbau

3.1 LED-Frontplatte

Die 28 10mm-LEDs pro angezeigter Ziffer sind mit einer Breite von 170 mm auf einer insgesamt 680*240 mm großen Plexiglasscheibe angebracht. Jeweils vier LEDs sind zu einem Segment verdrahtet (siehe Bild oben). Jede Ziffer hat sieben Segmente.

Für das Bohren der 112 Löcher werden die vier DINA4-Ausdrucke der Ziffern (siehe das Open-Office-Draw-Dokument mit den Zeichnungen hier) auf die Plexglasplatte aufgeklebt und mit einem 1,5mm-Bohrer vorgebohrt. Das Aufbohren mit immer größeren Bohrern erfolgt behutsam, damit die Platte nicht ausreißt, und mit niedriger Geschwindigkeit, damit das Plexiglas beim Bohren nicht schmilzt.

Ab 6mm wird mit einem schnelldrehenden Entgrater von vorne und von hinten auf etwa 9mm Durchmesser weitergebohrt. Bei der Verwendung einer Ständerbohrmaschine kommt danach der 10mm-Bohrer mit hoher Drehgeschwindigkeit und sehr langsamem Vorschub zum Einsatz. Das führt zwar zum Schmelzen des Plexiglases an der Bohrstelle, verhindert aber ein Ausreißen der Bohrung.

Für diejenigen Löcher, die mit der Ständerbohrmaschine nicht zugänglich sind, weil der Ständer im Weg steht, wird mit 7, 8 und 9mm langsam gebohrt und dann mit 10mm das Endloch gebohrt. Man kann auch mit einem scharfen Messer die Bohrung auf 10mm ausweiten, das ist am schonendsten und führt nicht zum Ausreißen.

Auf den Seiten 2 und 3 des Ausdrucks sind auch noch die beiden Mittel-LEDs eingezeichnet.

Zuletzt werden in der Mitte noch die beiden 10mm-Löcher für die Mitten-LEDs gebohrt. Deren Anode kann mit irgendeiner der vier anderen Anoden verdrahtet werden, ihre Platzierung ist im Assembler-Quellcode anzugeben.

Zum Schutz und zum Aufstellen der Uhr wird in vier bis fünf cm Abstand eine zweite Plexiglasscheibe der gleichen Größe mit sechs Abstandshaltern montiert.

3.2 Prozessor-Platine

Komponentenplatzierung beim Prozessor Das sind die Komponenten mit dem Prozessor auf einer 50x50mm großen Lochrasterplatine. Alle äußeren Anschlüsse sind mit Steckverbindern versehen, damit man die Platine auch nach dem Einbau und der Fertigstellung der Uhr noch ganz herausnehmen kann.

3.3 Netzteil-Platine

Bestückung des Netzteils Das Netzteil wird auf einer ebenfalls 50x50 mm großen Lochrasterplatine aufgebaut.


Seitenanfang Eigenschaften Hardware Aufbau Software

4 Software

4.1 Downloads

Der Quellcode in Assembler ist hier verfügbar und kann hier im Browser angesehen werden.

Die folgenden Dokumente sind zusätzlich im Open-Office-Format verfügbar:
  1. ein Tabellendokument mit allen Berechnungen (Timer, Ströme, Messwerte der LEDs, u.v.a.m. gibt es hier,
  2. die Schaltbilder des Prozessors und des des Netzteils gibt es hier,
  3. die Layouts der Prozessor- und der Netzteilplatine gibt es hier (nein, ich habe keine gedruckte Platine entwickelt),
  4. die vier Seiten des Siebensegment-Layouts gibt es hier.

4.2 Assemblieren des Quellcodes

Vor dem Assemblieren sollte noch einmal kontrolliert werden, dass im Quellcode keine Debugging-Schalter gesetzt sind (siehe unten).

Zum Assemblieren wird ein Assembler benötigt, der .IF-Direktiven beherrscht. Der ATMEL-Assembler 2 beherrscht das. Wer sich scheut, 900 MB ATMEL-Studio-Software herunterzuladen und zu installieren oder wer kein Windows-Betriebssystem hat, ist mit meinem Assembler gavrasm besser und einfacher bedient. Wie damit mit einem 64-Bit-Betriebssystem assembliert wird, findet sich für Windows hier und für Linux hier. Wer ein ganz anderes Betriebssystem (32-Bit, Mac-OS, etc.) hat, kann sich den Quellcode von gavrasm herunterladen und mit Free Pascal was Eigenes selbst kompilieren.

Der assemblierte Maschinencode sollte nach dem Assemblieren als .hex-Datei im gleichen Verzeichnis herumliegen.

4.3 Flashen, Fuses

Der Hexcode muss dann in den Flashspeicher des ATmega48 geschrieben werden. Das geht mit einem AVR-Brenner und der entsprechenden Software.

Fuses ATmega48 Vor dem ersten Programmieren sollten die Fuses des ATmega48 auf den externen Quarz umgestellt werden. Bitte dabei beachten, auch die CLKDIV8-Fuse zu löschen, die CKOUT-Option abzuschalten und die Brown-out detection entweder auf 1,7V einzustellen oder abzuschalten. In der Praxis erwies sich die Brown-Out-Detection bei 1,7V als wesentlich sensibler als eingestellt. So blockierte der Brownout schon, wenn die Betriebsspannung mal unter 2,5 V lag. Man schaltet die daher besser ganz aus und vermeidet so diesen Ärger.

Ob der Prozessor korrekt läuft, kann mit der Debug-Funktion überprüft werden, die die grüne LED blinken lässt (siehe hier).

4.4 Hardware-Diagnosen

Als Hilfe bei der Inbetriebnahme der Uhr können die folgenden Diagnosehilfen benutzt werden. Sie werden eingestellt, indem im Kopf der Quelldatei die entsprechenden Konstanten mit Yes versehen werden. Dabei macht es wenig Sinn, gleichzeitig mehrere Optionen anzuschalten, da sich diese teilweise gegenseitig ausschließen. Nach der Änderung jeweils neu assemblieren und die Flashdatei brennen.
  1. "Debug_ledgreen": Beim Einschalten dieser Option sollte die grüne LED, die an PC2 angeschlossen ist, hektisch blinken.



    Wenn die LED gar nichts tut, läuft der Prozessor nicht und man muss im Clock-Bereich auf Fehlersuche gehen. Blinkt die LED sehr langsam, wie hier:



    ist die CLKDIV8-Fuse noch gesetzt und der Prozessor arbeitet mit 512 kHz.
  2. "Debug_current": Alle acht Kathodentreiber werden aktiviert, mit einem Amperemeter kann der Konstanstrom an den Kathodenpins des Steckverbinders X2 nach +16V gemessen werden. Er sollte um die 27 mA betragen. Ist die LED-Anzeige angeschlossen, gehen alle sieben Segmente der Zehner-Stunden an.
  3. "Debug_segments": Das schaltet nacheinander die sieben Segmente a bis h jedes Segments ein und geht dann zur nächsten Ziffer. Nach der vierten beginnt die Ausgabe wieder von vorne. Die Geschwindigkeit kann mit der Variablen "cDebug_segDelay" herabgesetzt werden. Mit 1 geht es sehr flott, mit 10 schon etwas gemütlicher zu.
  4. "Debug_mux8" Diese Variante stellt in einer simulierten Multiplex-Ausgabe alle Ziffern-Leds (und den Doppelpunkt) an und gibt sie nacheinander auf den vier Ziffern aus. Die Multiplexfrequenz kann mit der Konstanten "cDebug_muxfreq" vorgewählt werden. Bei der Minimaleinstellung mit 4 Hz sieht man die einzelnen Ziffern noch einzeln leuchten. Bei Frequenzen von 20 bis 50 Hz ist ein deutliches Flimmern erkennbar. Bei 62,5 Hz ist das Flimmern fast nicht mehr zu merken. Oberhalb von 100 Hz ist garantiert nichts mehr zu bemerken.
  5. "Debug_adc": Die Messergebnisse des ADC, des MSB der ADC-Summe, werden in dezimalem Format auf der Anzeige ausgegeben.
  6. "Debug_keys": Die Eingangsignale an den beiden Tasteneingängen werden in den Zehnerstunden (Taste 1) und Einerstunden (Taste 2) angezeigt. Der Eingang wird als kleines i (Segment c der Anzeige) für High oder als kleines o für Low angezeigt.
  7. "Debug_dcferr": Alle Fehlerereignisse am DCF77-Eingang werden mit einem E-Fehlercode ausgegeben. Dabei bedeuten:
    1. oder leer: Kein Fehler
    2. Signal kürzer als für eine 0 erforderlich
    3. Signal kürzer als für eine 1 erforderlich
    4. Signal kürzer als für; eine Pause erforderlich
    5. Signal kürzer als für die fehlende Sekunde erforderlich
    6. Signal länger als für die fehlende Sekunde erforderlich
    7. Beim Minutenwechsel keine 59 Sekundensignale empfangen
    8. Minutenparität ungerade
    9. Stundenparität ungerade
    10. Kein Signal am DCF77-Eingang
    Korrekte Signaldauern überschreiben den Fehlercode mit einem Leerzeichen, so dass nur die Fehlernummern zu sehen sind.

    Treten diverse Fehlernummern gemischt auf, kann die Toleranzbreite in der Einstellvariablen cDcfTol erhöht werden
  8. "Debug_dcfany": Alle ausgewerteten Signaldauern werden von hinten nach vorne auf dem Display angezeigt: empfangene Nullen werden als kleines o angezeigt, empfangene Einsen mit einem kleinen i (c-Segment ist an), Pausen mit einem großen P.
  9. "Debug_dcfdur": Alle Signaldauern werden in hexadezimalem Format auf dem Display angegeben (die Hexadezimalziffern A, b, C, d, E, F in diesem Format).

4.5 Einstellmöglichkeiten der Software

Im Abschnitt "Adjustable constants" des Quellcodes können diverse Einstellungen im Quellcode vorgenommen werden, die die Eigenschaften der Uhr verändern. Alle in diesem Abschnitt vorhandenen Einstellungen können ohne Weiteres geändert werden.
  1. .equ xtal = 4096000 ; in Hz
    Wenn man einen anderen Quarz anschließen möchte als den 4,096 MHz: hier kann man dessen Frequenz angeben. Die Frequenz des Quarzes muss durch 4096 oder 8192 ohne Rest teilbar sein, sonst würde die Uhr ungenau. Im Open-Office-Tabellenkalkulationsblatt Timer im Dokument Berechnungen können entsprechende Berechnungen durchgeführt werden.
  2. .equ cClkpr = 4 ; Either two or four
    Hiermit kann der Vorteiler verstellt werden, aus dem sich die Taktfrequenz des Prozessors ergibt. Es können nur 2, 4 oder 8 sinnvoll verwendet werden. Der Effekt kann im Rechenblatt angeschaut werden.
  3. .equ cStartHours = 0x09 ; Start at 20:00 h
    .equ cStartMinutes = 0x59

    Das stellt die Uhrzeit ein, mit der die Uhr startet, wenn die Betriebsspannung angelegt wird.
  4. .equ cDcfOnly = Yes ; Display/Clear unsynced time
    Schaltet die Leds aus, solange noch keine DCF77-Synchronisation vorliegt.
  5. .equ tDcf0 = 100 ; 100 ms for a 0
    .equ tDcf1 = 200 ; 200 ms for a 1
    .equ tDcfP = 850 ; Pause for 0 and 1 to next second
    .equ tDcfM = 1850 ; Pause for 59th second pulse
    .equ tDcfT = 3000 ; Time-out of DCF signal

    Diese Parameter stellen die Dauer von DCF77-Signalen in Millisekunden ein. Falls das DCF77-Modul weit davon abweichende Dauern (über die Toleranz hinaus) liefert, kann man diese hier verstellen.
  6. .equ cDcfTol = 10 ; Tolerance in %
    Die unvermeidlichen geringfügigen Abweichungen bei der DCF77-Signaldauer lassen sich hier mit einem Toleranzwert in % einstellen. Abweichungen nach unten und oben werden so akzeptiert.
  7. .equ cAnDp = 3 ; Should be between 1 and 4
    Dies stellt ein, an welche Anodenleitung der Doppelpunkt in der Mitte angeschlossen ist.
  8. .equ tBounce = 50 ; Bouncing time, in ms
    Dies stellt ein, nach welchem Zeitraum das Torkeln der Tasteneingänge beendet sein muss. Taster mit noch längerer Torkelzeit können hier abgefangen werden.
  9. .equ cDimOpto = No ; Select the source
    Dieser Parameter wählt aus, ob der Optosensor (Yes) oder das Poti zum Dimmen verwendet werden soll (No).
Änderungen werden erst nach erneutem Assemblieren und nach Übertragung in den Flashspeicher wirksam.

4.6 Funktionsweise der Software

Die folgenden Einzelkapitel stellen die grundlegenden Funktionen der Software dar.

4.6.1 Zeitsteuerung

Die gesamte Zeitsteuerung ist mit dem Timer/Counter TC0 realisiert. Es gelten folgende Zeitbeziehungen:
  1. Quarzoszillator mit externem Quarz = 4,096 MHz,
  2. Taktvorteiler 4 mit CLKPR, Prozessortakt = 1,024 MHz,
  3. TC0-Vorteiler 8 mit Prescaler, TC0-Takt = 128 kHz,
  4. Fast-PWM-Modus mit TOP=255, TC0-Overflow-Int = 500 Hz.
Innerhalb des Overflow-Interrupts werden folgende Aufgaben erledigt:
  1. Ausgabe der nächstniedrigen Ziffer der Uhr und Einstellen der nächsten Anode nach links,
  2. Abwärtszählen des Halbe-Sekunden-Vorteilers um Eins, falls Null: Setzen der Halbe-Sekunden-Flagge und Abwärtszählen des Minutenvorteilers (von 120 auf Null), falls Null: Setzen der Minuten-Flagge,
  3. Falls der Torkelzähler der Tasten nicht Null ist: wenn eine oder beide Tasten gedrückt sind Neustart des Torkelzählers, falls nicht: Abwärtszählen des Torkelzählers.
Ferner wird TC0 dazu benutzt, um beim Erreichen des Compare-Wertes A die Anoden-Leitungen abzuschalten (Dimm-Funktion). Dies erfolgt in der Interrupt-Service-Routine für Compare A.

Da sich der Compare-Wert nach Auswerten der Potentiometer-Stellung bzw. des Opto-Sensors relativ häfig ändert, war Vorsorge dagegen zu treffen, dass der neue Wert kleiner als der aktuelle Zählerstand werden kann, weil in diesem Fall der Compare-Match verfehlt wird und die Anoden bis zum Ende des Zyklus an bleiben. Das wird durch den Betrieb des TC0 im Fast-PWM-Modus verhindert, weil dann der geänderte Wert zwischengespeichert und erst beim nächsten PWM-Zyklus angewendet wird.

4.6.2 AD-Wandler-Steuerung als weitere Taktquelle

Der AD-Wandler arbeitet mit einem Clock-Prescaler von 128 und wandelt entweder die Analogspannung am Potentiometer an ADC0 (Dimmen mit Poti, Zeiteingabe mit Tasten) oder des Fototransistors an ADC1 aus (Dimmen mit Optosensor, keine Zeiteingabe aktiv).

In der Interrupt-Service-Routine des ADC werden jeweils 64 dieser Messwerte aufsummiert. Sind diese komplett, wird das MSB des Ergebnisses kopiert und eine Flagge gesetzt. Je nachdem in welchem Modus die nächsten 64 Wandlungen erfolgen, wird der AD-Multiplexer mit dem entsprechenden Kanal neu eingestellt.

Daraus ergibt sich folgendes Frequenzschema der AD-Wandlung:
  1. Prozessortakt: 1,024 MHz
  2. Clock prescaler: 128
  3. Anzahl Takte pro Wandlung: 13
  4. Anzahl Wandlungen pro Zyklus: 64
  5. Wandlungsfrequenz: 9,62 Hz
  6. Zeitbedarf: 104 ms

4.6.3 Multiplexen

Die vier Bytes mit den bei den vier Ziffern einzuschaltenden Leds sind im SRAM abgelegt. Sie werden mit 500 Hz im TC0-Overflow-Int nacheinander ausgegeben. Die Ausgabe erfolgt in umgekehrter Reihenfolge von Ziffer 4 nach Ziffer 1, weil sich dann das Ende des Zyklus leichter feststellen lässt.

Bevor die nächste Byte-Kombination ausgegeben wird, werden die Anodentreiber abgeschaltet, so dass kein zeitweises Überblenden erfolgen kann.

4.6.4 Einstellung der Zeit mit den Tasten

Die Einstellung der Zeit wird gestartet, wenn Taste 1 das erste Mal auf niedriges Potenzial geht. Dies wird im PCINT festgestellt, der für die beiden Tasteneingänge ermöglicht ist. Der Tasteninterrupt wird nur akzeptiert, wenn der Torkelzähler auf Null steht und der Tasteneingang auf Low geht.

Das Drücken von Taste 1 bewirkt, dass eine Flagge gesetzt wird. Diese Flagge schaltet die AD-Wandler-Messungen auf den Poti-Eingang um. Die fertigen Messwertsummen werden im Hardware-Multiplikator des ATmega48 mit 24 multipliziert, das Ergebnis in BCD umgewandelt, die beiden Nibble in Siebensegmentformat umkodiert und in die ersten beiden Zellen des Multiplexspeichers geschrieben (Stundenanzeige). Befindet sich der Sekundenteiler der Uhr in weniger als 25% Restzeit, dann erfolgt das nicht und die beiden Stellen werden durch Schreiben von Nullen geleert. Dadurch wird das Blinken erreicht.

Der nächste Tastendruck auf Taste 1 (nach Ablauf der Torkelzeit) bewirkt, dass zusätzlich das Minuteneingabe-Flag gesetzt wird. Die Messwerte werden dann mit 60 multipliziert und die Siebensegment Kodierung in den Stellen 3 und 4 des SRAM-Speichers abgelegt.

Ein dritter Tastendruck auf Taste 1 setzt die nunmehr eingestellte Zeit in die aktuellen Zeitregister, stellt den Sekunden- und den Minutenteiler auf ihren Anfangswert und löscht eventuell bereits gesetzte Flaggen des Zeitgebers. Ab jetzt wird wieder die Uhrzeit ausgegeben.

Drücken auf Taste 2 bewirkt, dass um eine Stelle zurück gewechselt wird (von Minuten auf Stunden, von Stunden auf Eingabe-Aus).

Jeder Tastendruck setzt den Torkelzähler auf einen Anfangswert. Er wird vom TC0-Overflow-Interrupt alle zwei Millisekunden um Eins vermindert, solange keine Taste gedrückt ist. Dieser Mechanismus unterbindet Tastenprellen.

4.6.5 Einstellung der Zeit mit DCF77

Jede Pegeländerung am DCF77-Eingang löst einen PCINT aus und eine Flagge wird gesetzt.

Die gesetzte Flagge bewirkt außerhalb der Interrupt-Service-Routine, dass der Zählerstand des TC1 abgelesen wird. Dieser wird mit einem Vorteiler von 1.024, also mit 4.000 Hz getaktet, was einer Zeit von 0,25 ms pro Zählererhöhung entspricht. Der Zähler wird mit jeder Eingangsflanke wieder rückgesetzt, so dass die Dauer jeder Pegeländerung exakt erfasst wird.

Auswertung der DCF77-Signaldauer Ein Null-Bit von DCF77 sollte um die 100 ms lang dauern, setzt man 10% Toleranz an ist 90 bis 110 ms eine zulässige Dauer. Mit dem Takt des TC1 entspricht dies einem Zählerstand zwischen 360 und 440. Liegt die Dauer eines Signals in diesem Bereich, handelt es sich um eine übertragene Null.

Entsprechend hat jede Signaldauer ihre Zuordnung. So liegt ein Minutenwechsel mit 1800 bis 1900 ms und bei 10% Toleranz irgendwo zwischen 1665 (Zählerstand 6660) und 2035 (Zählerstand 8140). Da bei allen Pegelwechseln ein Interrupt auftritt, ist auch die Pause zwischen einer Null oder Eins bis zum nächsten Sekundenbeginn eine zulässige Signaldauer (Sekundenpause).

Daraus ergibt sich folgender Algorithmus:
  1. Ist die Signaldauer kürzer als der erste Wert, liegt ein Fehler vor.
  2. Ist die Signaldauer gleich oder höher als der erste Wert und kleiner als der zweite Wert, liegt eine Null, eine Eins, eine Sekundenpause oder ein Minutenwechsel vor.
  3. Liegt die Signaldauer bei oder über dem zweiten Wert, muss die nächste Kategorie geprüft werden. Ist der Minutenwechsel überschritten, liegt ebenfalls ein Fehler vor.
Nullen und Einsen werden mit ROR in einen Pufferspeicher eingeschoben, der mindestens 40 Bits fasst. Dabei werden sie gezählt.

Sekundenpausen werden ignoriert und übergangen.

Tritt ein Minutenwechsel auf, dann
  1. wird geprüft, ob exakt 59 Datenbits eingegangen waren,
  2. werden die Minuten aus dem Bitstrom extrahiert, auf ein korrektes Paritäts-Bit (even parity) hin überprüft und in den Minutenspeicher abgelegt,
  3. werden die Stunden extrahiert, ebenfalls auf ein korrektes Paritätsbit hin geprüt und im Stundenspeicher abgelegt,
  4. sind beide korrekt empfangen, werden Stunden und Minuten in die Zeitregister kopiert, die Sekunden- und Minutenteiler neu gestartet und zwischenzeitlich gesetzte Flaggen gelöscht.


Zahlenwerte der DCF77-Signaldauer Dies sind die Zahlenwerte der Tabelle mit den Dauern der DCF77-Signale in TC1-Timer-Ticks im Normalfall. Man sieht, es gibt keine Überlappung. Und immerhin entspricht jeder Timer-Tick 1.024 Einzelschritten des Prozessors, so dass auch bei einer zeitlichen Verspätung des Ablesens des Wertes keine wesentliche Verzögerung eintritt.

Seitenanfang Eigenschaften Hardware Aufbau Software


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

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