Serielle Arduino-Software - Vollduplex

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.

Antworten (5)

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:

  1. Weisen Sie dem Serial-Polling-ISR maximale Priorität zu und führen Sie es vorzugsweise mit dem 3-fachen der gewünschten Datenrate aus. Abtasten Sie alle Ihre Eingaben und schreiben Sie alle Ihre Ausgaben zu Beginn dieser Interrupt-Routine und finden Sie dann heraus, was die Ausgaben für den nächsten Durchlauf sein sollten. Dies trägt dazu bei, jeden zeitlichen Versatz zu minimieren, der andernfalls durch eine variable Interrupt-Verarbeitungszeit verursacht werden könnte.
  2. Anstatt eine Zustandsmaschine als solche zu verwenden, kann es für den Empfänger hilfreich sein, die eingehenden Daten effektiv in ein großes Schieberegister zu verschieben. Wenn das Bitmuster anzeigt, dass ein Byte empfangen wurde, greifen Sie die Daten und löschen Sie die entsprechenden Bytes.
      ... 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).

Beide seriellen Leitungen müssen gleichzeitig aktiv sein. Ich kann in diesem Design keine Hardware hinzufügen.

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.

Ich denke, er ist ein Bach, wenn er die Hardware nicht erweitern oder ändern kann ... auch diesen Preis kann er genauso gut in einen ATMega644 werfen, der 2 Hardware-UARTs hat (und seine eigene SPI-Schnittstelle dafür schreibt) ... aber Ich denke, das besiegt den Teil "spart viel Arbeit" :)
An diesem Punkt sollten sie besser einen atmega1280 mit 4 Hardware-UARTs hineinschieben. Leider wird eine Hardwarelösung ihre Anforderungen nicht erfüllen.
@AdamDavis lol du hast mich auf einen leistungsfähigeren AVR gebracht :)
@AdamDavis Ich kenne offensichtlich nicht alle Einzelheiten dessen, womit Sie es zu tun haben, aber im Allgemeinen werden sie wechseln, selbst wenn ein Kunde sagt, dass er bei einem bestimmten Chip bleiben muss, wenn Sie ihm einen ausreichenden Grund zum Wechseln geben können.
Er benutzt einen Arduino und kann den Prozessor nicht ändern. Es ist ziemlich einfach, einen solchen Chip mit einem geeigneten Prototyping-Schild zu verbinden.
@Kellenjb Nehmen wir für die Zwecke dieser Frage an, dass sie nicht wechseln können. Natürlich verfolgen wir auch andere Optionen, aber diese Frage beschränkt sich bewusst auf Optionen, die keinen Wechsel der Hardware beinhalten.
@Adam Vielleicht möchten Sie Ihre Frage ändern, um anzuzeigen, dass Sie nicht bereit sind, Hardware zu ändern oder hinzuzufügen.

Erlaubt Ihnen der Client, ein Arduino Mega zu verwenden, das über 4 serielle Hardware-Ports verfügt?

http://www.arduino.cc/en/Main/ArduinoBoardMega

Warum das negative Votum?
Weil er vermutlich den Prozessor nicht wechseln kann.
Ich habe Sie nicht abgelehnt, aber der erste Teil der Frage weist darauf hin, dass ein Wechsel des Prozessors keine Option ist. Etwas vorzuschlagen, das das OP bereits ausgeschlossen hat, kann zu Downvotes führen ...
Dies wäre wahrscheinlich besser als Kommentar als als Antwort gewesen, aber das Ausloten der Grenzen der „Arduino“ -Anforderung scheint eine lohnende Idee zu sein, da Arduino technisch gesehen ein Markenname ist, der eine Vielzahl von Boards umfasst, obwohl es häufig eine Abkürzung für das aktuelle ist beliebte mega328p&mega8u-Baugruppe.

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.

Das in die Arduino-1.0-Entwicklungsumgebung integrierte SoftwareSerial ist im Wesentlichen NewSoftSerial. Ich habe NewSoftSerial nur für den Fall ausprobiert, aber das Problem ist das gleiche - es kann nicht empfangen, während es sendet.
Sie können die Details des Fehlers hier sehen: arduino.cc/forum/index.php/topic,81756.0.html Ich habe sie gebeten, die Dokumentation zu aktualisieren, damit spätere Benutzer nicht in diese Falle tappen.
Ich würde sagen, die Machbarkeit von Mehrkanalkommunikation hängt wirklich vom Verhältnis von Baudrate zu Taktrate ab. Langsam genug und Sie haben genügend Zeit, um mehrere Sende- und Empfangskanäle zu handhaben.