Ich brauche zwei serielle Ports für dieses Atmega328-Arduino-Projekt, aber dieser Prozessor hat nur einen Hardware-UART. Der Prozessor, das Hardwaredesign und die Programmierumgebung sind bereits festgelegt, und ich kann die Hardware oder den Prozessor überhaupt nicht ändern, daher ist eine Softwarelösung erforderlich.
Die mitgelieferten Arduino-Bibliotheken bieten eine SoftwareSerial-Bibliothek, die meiner Erfahrung nach nur halbduplex ist - während der Senderoutine werden Interrupts deaktiviert, was natürlich bedeutet, dass die Interrupt-gesteuerte Empfangsroutine heruntergefahren wird.
Bevor ich meine eigene Vollduplex-Bibliothek implementiere, wollte ich herausfinden, ob andere eine einfache Lösung dafür gefunden haben oder ob es Bibliotheken gibt, die es korrekt implementieren.
Ich habe das Arduino nicht verwendet, aber effiziente Soft-UARTs auf einer ganzen Reihe von Plattformen geschrieben. Welcher Ansatz auf einer bestimmten Plattform am besten ist, hängt davon ab, welche Arten von Bit-Munging-Operationen sie am effizientesten ausführen kann. Ein paar Anregungen hätte ich aber:
... kurz vor Beginn des Interrupts (für konsistentes Timing) shiftreg >>= 1; wenn (IN_PORT) shiftreg |= 0x20000000; ... andere Interrupt-Logik, dann ... if ((shiftreg & 0x20000007) == 0x20000001) { int-Ergebnis = 0; if (shiftreg & 0000000040) result |= 1; // Hinweis: Konstanten sind OCTAL! if (shiftreg & 0000000400) result |= 2; if (shiftreg & 0000004000) result |= 4; if (shiftreg & 0000040000) result |= 8; if (shiftreg & 0000400000) result |= 16; if (shiftreg & 0004000000) result |= 32; if (shiftreg & 0040000000) Ergebnis |= 64; if (shiftreg & 0400000000) result |= 128; // Tue etwas Passendes mit dem Ergebnis, dann... shiftreg |= 0x3FFFFFFFF; } sonst wenn (shiftreg = 1) { ... etwas mit langer Pause machen (wird genau einmal erkannt) }
Beachten Sie, dass die Zeit im schlimmsten Fall erheblich sein kann, die Zeit im normalen Fall jedoch ziemlich schnell sein wird. Wenn ein ankommendes Byte erkannt wird, könnte man es ferner in ein anderes Speicherwort kopieren und das Bit-Munging bei einem späteren Interrupt durchführen. Da die serielle Übertragung nur bei jedem dritten Interrupt etwas tun muss, könnte das Bit-Munging bei Interrupts durchgeführt werden, bei denen die Routine für die serielle Übertragung nicht ausgeführt wird.
Sie sagen, dass Sie vorhandene Hardware nicht ändern können - können Sie hinzufügen? Wenn nicht beide seriellen Leitungen gleichzeitig aktiv sein müssen, können Sie einen Multiplexer oder einen analogen Schalter an den UART-Leitungen verwenden und zwischen den beiden zu bedienenden Geräten hin und her schalten. Sie müssen beim Umschalten nur sicherstellen, dass der Pegel an Ihrem TX-Pin hoch bleibt, wenn er vom UART weggeschaltet wird (um eine falsche START-Bedingung zu verhindern).
Als ich einen zweiten Hardware-UART auf einem AVR benötigte, habe ich ein MAX3100-Gerät verwendet. Es verfügt über eine SPI-Schnittstelle und ist sehr einfach zu bedienen. Sie sind recht teuer, ersparen aber viel Arbeit.
Erlaubt Ihnen der Client, ein Arduino Mega zu verwenden, das über 4 serielle Hardware-Ports verfügt?
Verwenden Sie nicht SoftSerial, verwenden Sie zumindest NewSoftSerial ... Ich denke, es ist eine wirkliche Herausforderung (vielleicht sogar unmöglich), eine Mehrkanal-Vollduplex-UART-Kommunikation ohne zwei Hardware-UARTs durchzuführen ... mit NewSoftSerial denke ich das Opfer Sie machen, dass Sie jeweils nur einen Kanal "benutzen" können. Ich denke, wenn es mit Arduino gemacht werden könnte, wäre es jetzt gemacht worden.
Siehe Diskussion hier über die Verwendung mehrerer Instanzen von NewSoftSerial.
Adam Davis