Es gibt einen netten Trick, den Sie ausführen können, wenn die Kommunikation jeweils nur in eine Richtung erfolgt (dh Halbduplex-Kommunikation). Es wird nicht funktionieren, wenn beide Seiten gleichzeitig miteinander sprechen (Vollduplex), aber wenn es Ihr typisches "mach das" ist "ok hier ist die Antwort" "jetzt mach das" "ok hier ist die neue Antwort" Art der Kommunikation es funktioniert ganz gut.
Da die UART-Verbindung einen Leerlaufzustand des Senders auf einem logisch hohen (1) Pegel verwendet, würden Sie ein UND-Gatter mit 2 Eingängen verwenden und den TX von jeder Seite mit einem UND-Eingang verbinden. Der Ausgang des UND-Gatters ist Ihr Eingang zum UART Ihres Sniffers (es ist der RX-Pin). Nehmen Sie nun die TX-Leitung von Gerät B und bringen Sie sie an einen E / A-Anschluss am Sniffer. Sie konfigurieren den Sniffer so, dass ein Interrupt generiert wird, wenn dieser Pin von hoch nach niedrig wechselt.
Um es noch einmal zusammenzufassen: Gerät A UART TX -> AND-Gate-Eingang. Gerät B UART TX -> anderer UND-Gatter-Eingang UND Sniffer-GPIO-Pin. Ausgang des UND-Gatters -> Sniffer-UART-RX-Leitung.
Die UART-Kommunikation besteht aus einem Startbit, einer bestimmten Anzahl von Datenbits, einem optionalen Paritätsbit und einem oder mehreren Stoppbits. Da der Ruhezustand ein logisch hohes (1) ist, ist der Start JEDES Bytes ein logisches niedriges (0) und der Interrupt auf dem Sniffer wird ausgelöst. Während Ihr Sniffer den E / A-Interrupt ausführt, sammelt die UART-Hardware Bits vom UND-Gatter. Wenn der UART das Stoppbit empfangen hat, ist der E / A-Interrupt lange abgeschlossen und der UART RX-Interrupt wird ausgelöst.
Die Interrupt-on-IO-Änderungsroutine setzt eine "Richtungs" -Variable, um anzuzeigen, dass die Kommunikation in der "B-> A" -Richtung erfolgt. Der UART-Empfangsinterrupt des Sniffers würde diese "Richtungs" -Variable betrachten und das gerade empfangene Byte in den entsprechenden Puffer schreiben. Der UART RX-Interrupt würde dann die Variable "Richtung" auf den Standardzustand "A-> B" zurücksetzen:
volatile int direction = 0; /* 0 = A -> B */
void io_interrupt(void)
{
direction = 1; /* switch direction, now B -> A */
}
void uart_interrupt(void)
{
unsigned char b;
b = UART_RX_REG;
if(direction) {
store_byte_to_device_b_sniff_buffer(b);
} else {
store_byte_to_device_a_sniff_buffer(b);
}
direction = 0; /* reset direction to default A -> B */
}
Dieser Code ist aus Gründen der Klarheit geschrieben und nicht unbedingt das, was Sie in einer realen Situation schreiben würden. Persönlich würde ich "Richtung" zu einem Zeiger auf die entsprechende FIFO-Struktur machen, aber das ist eine ganz andere Übung. :-)
Wenn Gerät A spricht, bewegt sich die E / A-Leitung nicht (sie bleibt auf einer logischen '1', da der UART-Sender von Gerät B inaktiv ist), und der UART RX-Interrupt empfängt ein Byte. Achten Sie darauf, dass die Richtung A-> B ist und speichern Sie die Daten in diesem Puffer. Wenn Gerät B spricht, wird die E / A-Leitung niedrig, sobald Gerät B beginnt, Daten zu verschieben, und die E / A-Interrupt-Routine legt die Richtung fest, um anzuzeigen, dass Gerät B spricht. Der UART RX-Interrupt wird schließlich ausgelöst, nachdem alle Bits gesammelt wurden, und da der E / A-Interrupt dafür gesorgt hat, dass das Richtungsregister entsprechend eingestellt wird, wird das empfangene Byte im richtigen Puffer gespeichert.
Presto: Halbduplex-Kommunikation zwischen zwei Geräten, die mit einer einzigen UART- und E / A-Leitung auf dem Sniffer erfasst wurden, ohne bitgebundene UART-Kommunikation.