Eine Ampel aus TTL-Bausteinen

Hintergrund

Nicht-programmierbare Logikbausteine haben mich schon seit jeher fasziniert. Die einzelnen Bausteine sind in ihrer Funktion klar definiert und eng begrenzt, was sie universell einsetzbar macht. Miteinander kombiniert lassen sich nahezu beliebig komplexe System bauen. Erinnert ein wenig an richtig gemachte objektorientierte Programmierung. ;-)

Viele Aufgaben aus dem Bereich Steuerung und Regelung lassen sich durch Zustandsautomaten lösen. Ein Zustandsautomat besteht aus einer Menge von Zuständen sowie Bedingungen unter denen die Zustände gewechselt werden. Eine sehr primitive Unterart der Zustandsautomaten sind zeitlich getaktete Sequenzen, also Folgen von Zuständen die in immer gleicher Reihenfolge eingenommen werden und deren Wechsel durch einen regelmäßigen Takt ausgelöst wird. Ein schönes Beispiel ist eine Ampel-Steuerung, bei der die einzelnen Zustände definieren, welche der verfügbaren Lampen jeweils leuchten. In Form eines Zustandsdiagramms sähe das so aus:

Elemente der Schaltung

Die einfache Ampel-Schaltung besteht aus drei wesentlichen Elementen:

Der Taktgeber sorgt für eine regelmäßige Umschaltung zwischen den Zuständen. Hier gibt es verschiedene Möglichkeiten, ich habe mich für einen NE555 entschieden. Die im Schaltplan angegebenen Bauteilwerte sorgen für einen Takt von ca. 0,2 Hz, d.h. die Ampel schaltet alle 5 Sekunden in den nächsten Zustand. Auf diesen Teil der Schaltung werde ich nicht weiter eingehen, wer mehr erfahren möchte kann dies in der Application Note AN170 von Philips finden (sehr ausführlich).

Der Zustandsautomat implementiert das bereits gezeigte Zustandsdiagramm in Form eines 2-Bit-Binärzählers. Dieser besitzt genau 4 Zustände und läuft danach über, sodass er wieder von vorne beginnt. Ich habe ihn aus zwei kaskadierten D-Flip-Flops (74LS74) aufgebaut.

Die Dekodier-Logik ist für die Abbildung der Zählerstände auf die Farbkombinationen zuständig. Sie ist als einfache Wahrheitstabelle implementiert, wobei wir sehen werden, dass hierzu 3 NAND-Gatter ausreichen. Dies übernimmt ein einzelner 74LS00, dessen Ausgänge praktischerweise stark genug sind um die LEDs direkt zu treiben.

Der Binärzähler

Die D-Flip-Flops im 74LS74 besitzen jeweils 4 Ein- und 2 Ausgänge (neben den gemeinsam verwendeten Pins zur Spannungsversorgung) mit folgender Bedeutung:

Bezeichnung Richtung Bedeutung
PRE Eingang Preset (low active)
CLR Eingang Clear (low active)
CLK Eingang Clock (steigende Flanke)
D Eingang Eingang
Q Ausgang Ausgang
Q\ Ausgang Invertierter Ausgang

Low active bedeutet, dass der Pin seine Funktion ausübt wenn er auf GND (low) gezogen wird. Eine Besonderheit der TTL-Bausteine der 74LS-Familie (Low-power Schottky) ist, dass nicht beschaltete Eingänge automatisch auf VCC (high) liegen. Man darf sie daher unbeschaltet lassen wenn man sie nicht benötigt, anders als z.B. bei CMOS-Logik (wie etwa die 74HC-Familie).

Ein D-Flip-Flop übernimmt in jedem Taktzyklus den am Eingang D anliegenden Zustand, in diesem Fall also bei jeder steigenden Flanke an CLK. Der Ausgang Q zeigt immer den Zustand des Flip-Flops an, während Q\ den invertierten Zustand anzeigt. Durch Rückkopplung des Ausgangs Q\ auf den Eingang D wird der Zustand des Flip-Flops bei jedem Taktzyklus invertiert (umgangssprachlich "getoggelt"). Das geht deshalb gut, weil jeder Logik-Baustein eine gewisse Zeit benötigt um die Eingangswerte auf die Ausgangswerte abzubilden (die sog. propagation delay time, bei 74LS in der Größenordnung von 10 - 20 Nanosekunden, abhängig von der Funktion des Bausteins) und der Pegel des Taktsignals nur einmal pro Zyklus die Schaltschwelle überschreitet. Bei zu langsamen Taktsignalen kann es bei solchen Schaltungen zu komischen Effekten kommen (habe ich gehört, aber noch nicht selbst erlebt).

Durch Kaskadierung mehrerer dieser "Toggel-Zellen" kann man einen Zähler bauen. Verbindet man den Q-Ausgang des ersten Flip-Flips mit dem CLK-Eingang des zweiten, dann führt ein 0/1-Wechsel im ersten Flip-Flop zum Toggeln des zweiten Flip-Flops:

In diesem Fall erhält man einen 2-Bit-Zähler der rückwärts zählt: 11, 10, 01, 00. Das liegt daran, dass der Q-Ausgang weitergegeben wird und das Flip-Flop auf steigende Flanken reagiert. Angenommen die Flip-Flops haben alle initial den Speicherwert 0 und der erste Takt führt zum Wechsel von 0 auf 1 des ersten Flip-Flops, dann sieht dies für das zweite Flip-Flop genauso wie das ursprüngliche Taktsignal aus und es wechselt ebenfalls von 0 auf 1. Beim zweiten Takt wechselt das erste Flip-Flop von 1 auf 0, was auf das zweite Flip-Flop keine Wirkung hat (es triggert nur auf steigende Flanken). Erst der nächste Wechsel von 0 auf 1 im ersten Flip-Flop führt zu einem Wechsel von 1 auf 0 im zweiten Flip-Flop.
Möchte man einen Vorwärtszähler realisieren, muss dementsprechend der invertierte Q\-Ausgang auf den Takt-Eingang des folgenden Flip-Flops geschaltet werden.

Für unseren Anwendungsfall ist es egal, in welchem Zustand der Zähler startet. Würde dies eine Rolle spielen, dann müssten die Eingänge PRE und CLR benutzt werden: PRE setzt das jeweilige Flip-Flop auf 1, CLR auf 0.

Die Dekodier-Logik

Die Aufgabe der Dekodier-Logik ist für jede der drei LEDs ein Signal zur Verfügung zu stellen, das anzeigt wann die jeweilige LED zu leuchten hat. Hier kommt eine weitere Besonderheit der 74LS-Logik zum Tragen: Ausgänge sind gute Stromsenken, aber eher mäßige Stromquellen. Anders ausgedrückt: sie können stärker nach GND als nach VCC ziehen. Das ist für uns nicht besonders schlimm, wir können die LEDs so verbauen, dass ihre Anoden per Vorwiderstand an VCC liegen und ihre Kathoden über die Logik-Ausgänge nach GND gezogen werden, wenn die LEDs leuchten sollen. Wir müssen uns aber dieser invertierten Logik immer bewusst sein: bei 1 ist die LED aus, bei 0 ist die LED an.

Was benötigt wird ist also eine Logik-Schaltung die folgende Tabelle implementiert:

Q2 Q1 Rot Gelb Grün Beschreibung
1 1 0 1 1 Rot
1 0 0 0 1 Rot-Gelb
0 1 1 1 0 Grün
0 0 1 0 1 Gelb

Das Vorgehen ist für jede LED die Zustände von Q1 und Q2 anzusehen und ein Muster zu erkennen, wie der Zustand daraus abgeleitet werden kann. Es gibt auch formale Methoden (z.B. Karnaugh-Veitch-Diagramme) die das Auffinden des optimalen Ausdrucks vereinfachen, aber bei nur zwei Bits ist das meiner Meinung nach etwas übertrieben. Ich bin auf folgende Ausdrücke gekommen:

 Rot: NOT Q2
 Gelb: Q1
 Grün: Q2 OR NOT Q1

Nun hatte ich schon verraten, dass ein 74LS00 (NAND-Gatter mit je 2 Eingängen, 4 Stück pro Baustein) zum Einsatz kommen soll. NAND-Gatter haben (ebenso wie NOR-Gatter) die Eigenschaft, dass aus ihnen alle anderen Logik-Verknüpfungen dargestellt werden können. Dazu hilft es sich die Wahrheitstabelle vor Augen zu halten:

Input A Input B Output
0 0 1
0 1 1
1 0 1
1 1 0

Um ein logisches NOT zu erhalten verbindet man einfach beide Eingänge und erhält somit die Zeilen 1 und 4, bei denen der Ausgang immer das Gegenteil beider Eingänge ist. Anders ausgedrückt: NOT(A) entspricht NAND(A, A). Man könnte aber auch sagen NAND(1, A), sich also auf Zeilen 3 und 4 der Tabelle beschränken und durch A auswählen lassen.

Um ein OR darzustellen muss man etwas tiefer in die Trickkiste greifen. Benötigt wird eine Schaltung, bei der am Ausgang nur dann 0 anliegt, wenn an keinem der Eingänge 1 anliegt. Diese "keiner von allen"-Eigenschaft als Alleinstellungsmerkmal hat die letzte Zeile, nur falsch rum. Wenn man also A und B jeweils invertiert kommt man auf: NAND(NAND(A, A), NAND(B, B)) bzw. NAND(NAND(1, A), NAND(1, B)).

Wen das fasziniert, der kann in der Wikipedia unter NAND-Gatter weiter lesen. Wir müssen jetzt unsere Eingänge mittels NAND auf die Ausgangs-Signale abbilden:

 Rot: NAND(1, Q2)
 Gelb: Q1
 Grün: NAND(NAND(1, Q2), Q1)

Bei der Umwandlung von OR in AND helfen die De Morganschen Gesetze (und ein Blatt Papier + Bleistift, mir zumindest).

Und nun noch einmal alles zusammen

Dem aufmerksamen Beobachter wird auffallen, dass die hier gezeigte Schaltung nicht exakt unserem letzten Entwicklungsstand der Dekodier-Logik entspricht:

Farbe Logik-Plan Schaltplan
RotNAND(1, Q2)NAND(1, Q2)
GelbQ1NAND(1, Q1\)
GrünNAND(NAND(1, Q2), Q1)NAND(Q2\, Q1)

Warum das? Bei "Gelb" wollte ich den Ausgang des Flip-Flops nicht durch die LED belasten. So eine LED ist deutlich hungriger als ein Logik-Eingang, und der Ausgang toggelt ja nicht zum Selbstzweck, sondern wir wollen saubere Flanken für das zweite Flip-Flop erzeugen. Sowohl bei "Gelb" als auch bei "Grün" können wir uns außerdem zu Nutze machen, dass die Flip-Flops bereits einen invertierten Ausgang mitbringen.

Nachdem ich die Funktion auf dem Steckbrett sorgfältig geprüft habe, habe ich das Ganze auch noch mal als Leiterplatte zum Anfassen hergestellt:

Ausblick

Natürlich kann man eine solche einzelne Ampel-Steuerung für nicht viel mehr als eine Modellbaulandschaft gebrauchen. Spätestens bei der Steuerung einer kreuzenden Straße stellt man fest, dass mehr Zustände benötigt werden (man darf ja nicht beiden Richtungen gleichzeitig "Gelb" geben, wir wissen ja: "Gelb bedeutet ganz schnell fahren"). Der vermeintlich einfachste Ansatz ist nach dem gezeigten Verfahren eine längere Zählerkette mit sich überlappenden Zuständen zu bilden. Spricht erst einmal nichts dagegen, führt aber eventuell zu einer recht komplexen Dekodier-Logik. Daher möchte ich zumindest einen alternativen Ansatz in den Raum stellen:

Die Idee ist, dass jede Ampel nach wie vor die bekannten 4 Zustände hat, aber das Weiterschalten der Zustände gesteuert wird. Damit lässt sich die Komplexität der Gesamtaufgabe recht gut in einzelne Module zerlegen, die ggf. auch einzeln überarbeitet und getestet werden können. Fehler können somit einfacher eingegrenzt werden. Auch hier zeigen sich Parallelen zur Software-Entwicklung. Verblüffend. ;-)

Downloads

Version Datum Änderungen Datei Beschreibung
1.1 2012-12-02 Bauteilwerte ergänzt, in aktuelles Eagle-Format konvertiert ttl-ampel-1.1.zip Schaltplan und Layout, Eagle-Format Version 6
1.0 2009-02-05 Erstes Release ttl-ampel-1.0.zip Schaltplan und Layout, Eagle-Format Version 4

Zurück zur Hauptseite