Schieberegister auf AVR simulieren (konfigurierbare Logik/Timer?)

Kürzlich habe ich zwei MCUs (ATtiny1616) eingerichtet, um grundlegende serielle Kommunikation mit selbst hergestellten Schieberegistern durchzuführen.

schematisch

Simulieren Sie diese Schaltung – Mit CircuitLab erstellter Schaltplan

Hier ist das Logikdiagramm für mein Schieberegister. Ich habe es aus logischen Gattern gemacht, die ich herumgelegt hatte. Alles, was sich auf der Datenleitung befindet, wird in das Register verschoben, wenn die Uhr (aktiv hoch) von hoch nach niedrig wechselt:

schematisch

Simulieren Sie diese Schaltung

Ignorieren Sie meine nicht standardmäßigen Flip-Flops, ich wollte die Bits auf meinem LED-Anzeigefeld visualisieren und vom niedrigstwertigen Bit (rechts) einschalten. Ich habe die Uhrleitung in den Empfänger verdrahtet, so dass sie nur PORTA.IN lesen würde , wenn die Übertragung beendet ist. Während jedes Byte übertragen wird, zählt TIMER A die fallenden Taktflanken im 8-Bit-Modus. Wenn der Zähler 8 erreicht, löst er einen Interrupt aus, der den Zähler zurücksetzt und PORTA.IN liest .

Der Empfänger/Slave zieht dann die Datenleitung auf Low und löst einen Interrupt auf dem Sender/Master aus, der nun untätig auf eine Übertragungsbestätigung wartet. Ich habe auch einen Timeout-Detektor hinzugefügt. Um das Ende einer Übertragung zu signalisieren, sende ich ein Byte mit allen Bits hoch. Der Empfänger erwartet keine Antwort zurück, nachdem er das letzte Byte empfangen und die Datenleitung auf Low gezogen hat, und die Übertragung ist abgeschlossen.

Ich habe dies mit zwei 512-Byte-Arrays getestet: einem leeren Byte-Array auf dem Empfänger und einem Array mit Bytes, die eine ASCII-Nachricht und einigen nachgestellten zufälligen Müll am Ende des Senders darstellen. Die Daten wurden in Sekundenbruchteilen erfolgreich vom Sender zum Empfänger übertragen. Ich bin ziemlich beeindruckt von den Ergebnissen.

Der Nachteil dieser Methode ist, abgesehen davon, dass sie derzeit nur eine Einwegkommunikation zulässt, dass sie einen ganzen Port zum Lesen der Daten belegt. Ich möchte, dass mein 'Schieberegister' intern in der MCU ist und nicht außerhalb meines Prototyps und viele E / A-Pins verschwenden. Dann könnte ich einfach die Uhr und die Daten in den Controller einspeisen und alles dort machen. Hardware natürlich nur bis zur letzten Lesung.

Irgendwelche Gedanken darüber, wie dies erreicht werden könnte? Der 1616 unterstützt konfigurierbare benutzerdefinierte Logik, aber ich glaube nicht, dass er die Anzahl der Eingänge hat, die für ein 8-Flip-Flop-Schieberegister erforderlich sind. Ich nehme an, ich könnte darauf zurückgreifen, Knabbereien auf einmal zu senden ... Ich habe auch darüber nachgedacht, Timer zu verwenden, um dies zu erreichen, aber ich weiß nicht, wie das gemacht werden könnte. Vielleicht eine Kombination aus beidem?

Antworten (2)

Der ATTINY161 enthält ein Hardware-Schieberegister, das im USART genau das tun kann, was Sie wollen ....

Geben Sie hier die Bildbeschreibung ein

Der USART ist sehr flexibel, sodass Sie ihn neben vielen anderen Konfigurationen problemlos zum Serialisieren/Deserialisieren von 8-Bit-Bytes basierend auf einem externen Takt einrichten können.

Die Dokumentation in den Datenblättern (USART ist in Abschnitt 24) ist vollständig und sehr gut, also würde ich das sorgfältig durchlesen.

Melden Sie sich wieder, wenn Sie spezielle Fragen dazu haben, wie Sie die Register speziell für Ihre Anforderungen einrichten können.

Alternativ könnten Sie die Uhr und die Daten in Leitungen mit beliebigen alten GPIO-Pins verbinden, einen Pin-Wechsel-Interrupt auf dem Uhr-Pin einrichten und dann den Daten-Pin in der Interrupt-Service-Routine abtasten und das neu abgetastete Bit in eine Variable oder verschieben Registrieren Sie sich, bis Sie volle 8 Bits erhalten. Ein kleiner Trick besteht darin, die Schieberegistervariable mit 0x01 zu initialisieren und dann das Übertragsbit nach jeder Linksverschiebung zu überprüfen - wenn es gesetzt ist, hat man 8 Datenbits (siehe warum). Dies erspart die Notwendigkeit einer zweiten Variablen, um die Bitanzahl zu halten.

Der ATtiny1616 verfügt sowohl im Master- als auch im Slave-Modus über eine I²C- ("TWI") und eine SPI-Schnittstelle.

Der SPI könnte genau das sein, was Sie wollen, aber werfen Sie auch einen Blick in den TWI. Es könnte die bessere Wahl sein, abhängig von Ihrer tatsächlichen Anwendung.

Das. Es ist einfach zu implementieren (obwohl man argumentieren könnte, dass es "weniger Spaß" machen würde), billiger herzustellen, Sie würden nur zwei Pins an Ihrem Mikro verwenden ... Probieren Sie es aus, OP! Sie haben all diese Peripheriegeräte aus einem bestimmten Grund auf dem Chip untergebracht :-)
Aha! Mir war nicht klar, dass die TWI-Hardware NICHT nur für I2C ist! Es ist ein Logikblock und hat ein 8-Bit-Schieberegister als Teil der Peripherie! Danke noch einmal!
I²C ist möglicherweise immer noch die bessere Option, da es nur zwei I/Os benötigt. Die Implementierung eines I²C-Slaves ist mit Hilfe des TWI nur ein paar Codezeilen lang.