UART-Transceiver für 8-Bit-Computer auf Steckbrett

In letzter Zeit interessiere ich mich immer mehr für die Montage von 8-Bit-Computern aus TTL- Chips. Ich war inspiriert von den wunderbaren Videos von Ben Iter auf YouTube sowie von verschiedenen Projekten auf der Hackaday- Website . Beim Entwerfen und Zusammenbauen meines eigenen 8-Bit-Computers dachte ich darüber nach, wie schwierig es sein würde, einen UART-Transceiver basierend auf einem IC der Serie 7400 zu implementieren. Die





letzte Schaltung: ein vorgefertigter UART-Transceiver, der aus einem IC



der Serie 7400 zusammengesetzt ist Lassen Sie uns zunächst herausfinden, was ein UART ist... Es ist ein universeller asynchroner Transceiver - ein einfaches Protokoll, mit dem Sie 8-Bit-Daten asynchron senden und empfangen können, damit ein Prozessor oder Computer mit der Außenwelt kommunizieren kann. Dies ist an sich nützlich - mein 8-Bit-Computer kann mit einem Laptop kommunizieren und ein Überwachungsprogramm für die serielle Schnittstelle (wie Kitt ) als Schnittstelle für die Texteingabe und -ausgabe verwenden. Noch interessanter ist, dass ich den OS-Bootloader für meinen 8-Bit-Computer programmieren und ihn dann über die UART-Verbindung vom Laptop aus programmieren kann! Da die Bluetooth-Module vom Typ HC-05 im Wesentlichen über den UART mit der CPU kommunizieren, kann ich das Bluetooth-Modul sogar verwenden, um meinen 8-Bit-Computer aus der Ferne zu programmieren! Es wäre wunderbar.



Einige Puristen würden das Programmieren eines 8-Bit-Computers mit einem viel leistungsstärkeren Computer als betrügerischen Ansatz betrachten - aber dies ist mein Projekt und es lebt nach meinen Regeln! Bitte programmieren Sie die handgefertigte Maschine mit DIP-Schaltern, wenn Sie lieber Daten eingeben als programmieren und eine authentische Arbeitserfahrung wünschen.



Was auch immer es mit der Programmierung war, zumindest habe ich mich entschlossen, mich bei der Entwicklung eines Computers auf einfache TTL-Chips zu beschränken - keine Arduino-, Raspberry Pi-, ESP8266- und andere Turing-komplette Module (was wäre sonst von Interesse?).



Einschränkungen des UART-Protokolls und des Designs



Vor Ihnen liegt die Struktur des UART- Signals . Es hat ein Startbit, das durch einen Übergang von hoch nach niedrig des Signals gekennzeichnet ist, gefolgt von einem Datenbyte (zuerst LSB) und dann einem Stoppbit, das das Signal hoch treibt. Manchmal gibt es auch ein Paritätsbit, aber es ist nicht erforderlich, deshalb habe ich es aus Gründen der Einfachheit weggelassen. Die Übertragungszeit für jedes Bit wird durch die Baudrate (in diesem Fall Bits pro Sekunde) bestimmt. Beispielsweise bedeutet eine Baudrate von 9600, dass ein Bit in

1/9600 = 104 μs übertragen wird. Die Wellenform ist recht einfach, so dass wir sie vollständig in Hardware auf Logikchips implementieren können.







Ich musste einen Quarzoszillator wählen, der mir Zugang zu Standard-Baudraten verschafft, die vorzugsweise durch Zweierpotenzen teilbar sind, damit ich bequem mit einem Binärzähler arbeiten kann. Nach einigem Überlegen entschied ich mich für einen 2,4576-MHz-Oszillator, da er die Übertragung mit 38400 Bit / s (geteilt durch 64) oder 9600 Bit / s (geteilt durch 256) ermöglichte.



UART-Sender



Liste der Komponenten:



  • 2,4576 MHz Quarzoszillator
  • 3 x 74LS161 4-Bit-Zähler
  • 74LS674 16-Bit-Schieberegister
  • 74LS06 UND
  • 74LS74 D-Trigger
  • 74LS04 NICHT
  • Diode 1N4001
  • 470 uF (!) Kondensator (Leistungsglättung)


Planen



Der UART-Sender ist am einfachsten zu verstehen. Grundsätzlich handelt es sich um ein paralleles Lastschieberegister mit seriellem Ausgang. Es lädt das Datenbyte, verfolgt die Start- und Endbits und synchronisiert es mit der gewünschten Baudrate. Das folgende Diagramm zeigt diesen Vorgang. In Teil (1) wird der 2,4576-MHz-Quarzoszillator unter Verwendung von zwei 4-Bit-74LS161-Zählern auf 38 400 Hz verlangsamt. In Teil (2) wird das 16-Bit-Schieberegister 74LS674 verwendet, um Daten für den UART zu synchronisieren. Ich benutze dieses Register, weil ich es bereits zur Hand hatte. Ich verstehe, dass dieser IC teuer und möglicherweise schwer zu finden ist, aber es hat definitiv mein gesamtes Schema vereinfacht.







Mit nur drei dieser ICs (zwei 4-Bit-Zähler und ein Schieberegister) können Sie einen kontinuierlichen Zeichenstrom mit 38.400 Bit / s (keine Parität) an den UART-Sender senden! Ja, es ist ein kontinuierlicher Stream - ich habe nicht berücksichtigt, dass das Schieberegister den Ladepuffer in einem Kreis aktualisiert. Ich brauchte dieses Verhalten nicht - ich wollte, dass der Prozessor jeweils ein Byte sendet. Die Dinge werden durch die Tatsache kompliziert, dass die Taktimpulse des Prozessors und des UART nicht synchronisiert sind, und ich wollte keine Annahmen darüber treffen, wessen Timer schneller ist, welches Signal zu welchem ​​Zeitpunkt relevant sein wird usw. Da ich Asynchronität zuverlässig handhaben musste, entschied ich mich für das folgende Schema, das gut funktioniert:



  • (3) Der Prozessor sendet ein Byte-Übertragungssignal, das nicht mit dem Prozessor und dem UART-Takt synchron ist.
  • «». ( AND 74LS06 D- 74LS74).
  • UART «» 4- 74LS161. UART.
  • (4) 16 , .


Beachten Sie, dass ich 16 Bit anstelle von 10 Bit des UART-Sendersignals verschiebe - hauptsächlich aufgrund der Bequemlichkeit, das Übertragsbit zum Deaktivieren der Sendeschaltung zu verwenden. Ich könnte einen Dezimalzähler verwenden (zum Beispiel den 74LS162), aber ich hatte keinen zur Hand, als ich die Schaltung auf einem Steckbrett zusammenbaute. Vielleicht werde ich im letzten Schema darauf umsteigen.



UART-Empfänger



Liste der Komponenten:



  • 2,4576 MHz Quarzoszillator (Sie können denselben Oszillator wie der Empfänger verwenden)
  • 3 x 74LS161 4-Bit-Zähler (können einen der ICs vom Empfänger verwenden)
  • 74LS74 D-Trigger
  • 74LS04 NICHT (kann Empfänger-IC verwenden)
  • Diode 1N4001
  • 470 uF (!) Kondensator (Leistungsglättung)
  • 220 Ohm Widerstände und LEDs für Schönheit.


Es scheint mir, dass der Empfänger etwas komplizierter sein wird, wenn der oben beschriebene UART-Sender leicht zu verstehen ist. Das Gute an der digitalen Logik ist jedoch, dass sie in separate Module aufgeteilt werden kann und dann nicht mehr alles so kompliziert erscheint!



Die Wellenformen in der unteren linken Ecke des folgenden Diagramms zeigen, was beim Empfang eines einzelnen digitalen Senderbits zu beachten ist. Woher wissen wir, ob ein Byte an uns gesendet wird? Einfach - das Startbit wird durch einen Übergang von hoch nach niedrig angezeigt, sodass wir diesen invertieren und den Übergang von niedrig nach hoch verwenden können, um das D-Flip-Flop (74LS74) (2) zu setzen.



Jetzt müssen wir mit dem Schreiben des Signals beginnen, indem wir es in Schieberegister verschieben und in der Mitte der Datenbitsequenz abtasten. Was ist wichtig zu verstehen: Da wir nicht wissen, wann wir Daten vom UART empfangen werden, ist dieser Prozess nicht synchron mit unseren Taktimpulsen. Je schneller unsere Impulse sind, desto näher kommen wir dem wahren Ursprung des Sendersignals. Der Einfachheit halber beträgt meine Taktrate das 16-fache der Baudrate (1). Dies bedeutet, dass jedes übertragene Bit 16 Impulse dieses Generators durchläuft. Um eine Probe ungefähr in der Mitte der übertragenen Daten zu entnehmen, müssen wir dies bei 8 tun - dafür erzeugen wir das Signal SAMPLING_CLK (3).



Bei der ansteigenden Flanke dieses neuen Taktsignals können wir dann das übertragene Signal mit zwei zugeordneten 8-Bit-Schieberegistern für serielle parallele Ausgänge (SIPO) in der Mitte jedes Datenbits synchronisieren. Bei der 16. Zählung erhalten wir ein digitales Bit, also erhöhen wir einen weiteren Zähler, der die Gesamtzahl der in (5) synchronisierten Bits verfolgt. Wenn dieser Zähler 16 erreicht (es könnte sich um einen Dezimalzähler handeln), wird die Empfangsschaltung durch Löschen des D-Flipflops deaktiviert. Puh! Ich gebe das folgende Diagramm und hoffe, dass Sie die Logik seiner Funktionsweise anhand meiner Beschreibung verfolgen können.







Leider habe ich kein Oszilloskop, und anfangs lieferte meine Schaltung einige mysteriöse Ergebnisse, indem sie ein Byte und dann ein anderes auf andere Weise akzeptierte. Ich habe den 2,4576-MHz-Oszillator gegen einen 1-Sekunden-555-Oszillator ausgetauscht, um die Zähllogik zu überprüfen, und ich habe ein Problem mit einem schwebenden Eingang am Pin eines der Zähler gefunden (ich habe mit LEDs debuggt). Ich habe beide Zähler-Reset-Pins mit dem RX_active-Signal verbunden, wodurch die Zähler zwischen Ein und Zurücksetzen umschalten, wodurch ihre Ausgabe am Ende jedes Datenerfassungszyklus gelöscht wird. Die Zähler funktionieren jetzt wie erwartet, und als ich den Oszillator wieder auf 2,4576 MHz stellte, begann alles korrekt und zuverlässig zu funktionieren.



Die letzte Computerschaltung auf dem Steckbrett verfügt über ein Ausgangsregister zur Steuerung der Datenausgabe an den Bus. Schließlich habe ich ein zusätzliches D-Flip-Flop am 74LS74 verwendet, um das RX_READY-Signal zu implementieren, das der Prozessor lesen kann, um zu überprüfen, ob das Byte bereit zum Lesen ist (dies gilt nur, wenn das Byte vollständig empfangen wurde).



Unten sehen Sie ein Foto des zusammengebauten und funktionierenden Computers. Die UART-USB-Schnittstelle ist der Dongle oben rechts. Die mittlere Karte enthält einen Quarzoszillator und 4-Bit-Zähler, die verschiedene Taktimpulse erzeugen. Oben neben der USB-Stromversorgung befindet sich ein 16-Bit-Schieberegister. Die linke Karte enthält die Logik für das gesteuerte Senden eines Bytes (UART TX). Sie sehen die Taste, mit der ich das Prozessorsteuersignal simuliert habe, und den 555-Timer, der als Prozessortaktimpuls fungiert. Das UART RX-Modul befindet sich auf der rechten Platine. Grüne LEDs zeigen den Empfang eines Bytes am Eingang an, gelbe LEDs zeigen den Datenempfang an (UART RX-Besetztzeichen) und rote LEDs leuchten auf, wenn das Byte vom Prozessor gelesen werden kann.





Auf der Suche nach hübscheren Steckbrettern und Verkabelungsfähigkeiten



Zusatz



Ich habe die Schaltung ein wenig optimiert (auf dem Weg habe ich eine Lektion über den Unterschied zwischen der Verarbeitung von asynchronen und synchronen Ereignissen in diskreter IC-Logik gelernt). Ich wollte die Anzahl der Chips reduzieren, indem ich einen Dezimalzähler verwendete, der die eingehenden Bits zählte und 10 statt 16 Bits zählte. Dann konnte ich das Schieberegister entfernen.



Ich habe zuerst den 74LS162-Zähler ausprobiert. Für ein Byte funktionierte alles, aber ich stellte schnell fest, dass es einen synchronen Rücksetzmechanismus hat - das heißt, es dauert einen Taktzyklus, um das Signal zurückzusetzen. Da die Uhr nach dem Empfang des letzten Bits stoppte, wurde der Zähler nicht gelöscht. Der 74LS161 4-Bit-Zähler, den ich entfernt habe, wurde asynchron zurückgesetzt, sodass zuvor alles funktioniert hat. Es ist gut, dass wir einen Dezimalzähler mit asynchronem Reset gefunden haben - 74LS160. Bei ihm funktioniert alles gut - siehe das aktualisierte Diagramm.







Überprüfen des empfangenen Bytes auf Fehler



Der Einfachheit halber habe ich im resultierenden Byte keine Fehlerprüfung hinzugefügt. Sie können sich vorstellen, dass wir jedes Mal, wenn eine "1" empfangen wird, ein Paritätsbit hinzugefügt und das Flip-Flop umgeschaltet haben. Dann würden wir wissen, ob wir eine gerade oder ungerade Anzahl von Bits empfangen haben, und könnten sie mit dem Paritätsbit vergleichen, indem wir das Flag setzen, wenn es nicht übereinstimmt. Darüber hinaus kann dies eine Überprüfung beinhalten, ob das Stoppbit gleich "1" war. Um Platz zu sparen, habe ich diese Funktionalität nicht hinzugefügt, möchte sie aber in Zukunft hinzufügen. Die Modularität des Projekts ermöglicht es Ihnen, dies nach Bedarf zu tun.



Anmerkungen



Ich liebe 8-Bit-Computer auf Steckbrettern und habe dieses Mini-Projekt genossen. Ich habe diese Schaltung schon seit einiger Zeit entworfen und war immer noch schockiert, als ich sie zusammenstellte und alles funktionierte. Das ist eine Art Magie! Fast.



All Articles