Ich verwende einen ATmega328P, um Daten mit einer hohen Baudrate (230400) an ein anderes Gerät zu senden. Das Gerät, an das ich Daten sende, unterstützt die Flusskontrolle und erhöht das RTS-Signal, wenn es die Übertragung halten muss. Das Problem ist, dass das Gerät erwartet, dass ich die Übertragung sofort stoppe, nachdem RTS bestätigt wurde.
Der ATmega328P hat einen Übertragungspuffer (UDR) und ein Schieberegister, von dem Daten an die TX-Leitung gesendet werden. Da der ATmega328P keine Flusskontrolle in Hardware unterstützt, implementiere ich sie in Software. Vor dem Senden (bevor ich in UDR schreibe) überprüfe ich RTS und warte, bis es niedrig wird, aber anscheinend reicht dies nicht aus, da Daten im Sendepuffer und im Schieberegister noch gesendet werden und ein vollständiges Byte immer noch gesendet werden könnte, nachdem RTS gesendet wurde wird bestätigt, wenn der ATmega328P seine Puffer leert.
Anscheinend hilft das Deaktivieren des Senders, wenn RTS aktiviert ist (setzen des TXEN auf Null), nicht, da es nicht wirksam wird, bis laufende und anstehende Übertragungen abgeschlossen sind, gemäß Dokumentationsabschnitt 19.6.5 .
Eine Problemumgehung könnte darin bestehen, zu warten, bis Transmit Complete (TXC) abgeschlossen ist, bevor jedes Byte gesendet wird, aber dies würde sich auf die Datenrate auswirken, da ich den Byte-Stream nicht hintereinander sende, selbst wenn RTS nicht aktiviert ist (ich fange an ein neues Byte erst senden, nachdem das vorherige vollständig gesendet wurde).
Gibt es mit dem ATmega328P eine Möglichkeit, die RTS-Flusskontrolle im Sender zu unterstützen und gleichzeitig das Pipelining des Sendepuffers und des Schieberegisters zu nutzen?
Klingt, als hätten Sie zwei grundlegende Probleme, ein schlecht konstruiertes externes Gerät und dass Sie versuchen, ungeeignete Hardware dazu zu bringen, eine Aufgabe zu erledigen, für die sie nicht vorgesehen ist.
Erstens: Benötigt dieses andere Gerät wirklich absolut keine Bytes mehr, nachdem RTS aktiviert wurde? Das wäre sehr ungewöhnlich. Es ist sehr üblich, dass Sender einen kleinen Puffer leeren, bevor sie RTS gehorchen. Wenn der andere Techniker also nicht weiß, was er tut, sollte das Gerät in der Lage sein, ein paar Bytes mehr zu tolerieren. Vielleicht kann es den "voll ausgestatteten" Fall von 16 weiteren Bytes nicht verarbeiten, aber es ist einfach schlechtes Design, 2-4 weitere Bytes nicht zuzulassen.
Zweitens, da Sie die Übertragung schneller beenden müssen, als die Größe des Ausgabepuffers, haben Sie die falsche Hardware gewählt. Ich kenne diese Reihe von Mikros nicht, aber das steht sicherlich im Datenblatt. Ich sehe drei Möglichkeiten:
Keiner dieser Kompromisse ist vielleicht das, was Sie wollen, aber das ist der Preis schlechter Architektur. Repariere es bei der nächsten Umdrehung oder antworte jetzt, wenn es wirklich wichtig ist. Die Welt hat nicht immer eine magische Antwort, nur weil dein Chef es jetzt will oder weil du dich in eine Ecke gemalt hast.
UDRn
plus ein Übertragungsschieberegister. Die SW kann auf UDRn
den nächsten zu sendenden Wert schreiben, während gleichzeitig der vorherige aus dem Schieberegister gesendet wird. Die Tatsache, dass die Übertragung nicht gestoppt werden kann, bis beide UDRn
und das Sendeschieberegister geleert sind, ist hier das Problem.UDRE
leer ist, aber was passieren sollte, ist, dass das nächste Byte nicht in die Warteschlange gestellt werden sollte, bis die Übertragung abgeschlossen ist. Dies ermöglicht eine Byte-für-Byte-Steuerung.
Ignacio Vazquez-Abrams
Rev
Amir Gonnen
Ignacio Vazquez-Abrams
Amir Gonnen
Amir Gonnen
Rev
Ignacio Vazquez-Abrams
Amir Gonnen
Amir Gonnen
UDREn
und nichtTXCn
.