回答:
私が正しく理解していれば、UARTを介して2つのデバイスが接続されています。デバイス間に接続されているTX、RX、GNDラインのみを想定していますか?(つまり、DTS / CTS / DTR / RTS制御ラインは使用されません-これは一般的です)。
このシナリオでは、デバイス1のTX(送信)がデバイス2のRX(受信)に接続され、その逆も同様です。それらのグラウンドは互いに接続されています。したがって、各デバイスは同時に送信と受信を行うことができます(それぞれが別のワイヤで送信され、通信は全二重です)。
私がこれすべてについて言及する理由は、「スニフ」または「リッスン」するには、会話の両側を聞くために2つのUARTが実際に必要になることが明らかになるためです。
基本的に、3つのデバイスすべてのUART GNDが短絡していることを確認し、デバイス1とデバイス2のTXラインを2つのRXラインに接続します(実際には、配管のようなTフィッティングのように「T字」) 2つのUART。ボーレートがすべて同じように設定されていることを確認してください。
Arduinoのボード/デザインはたくさんあります。最近最も一般的なもの、Duemilanoveは、1つのUART(まあ、USART)しかないATMega328Pを使用しています。したがって、2つ目のUART ICを配線するか、2つ目のレシーバーで「ビットバンギング」を使用する必要があります。
非同期UART通信は明確に定義されており、スタートビットとストップビット(場合によってはパリティビット)を備えているため、プロセッサの速度が十分であれば、デバイスのUART TXラインの1つを入力として構成されたGPIOに接続し、ラインをポーリングできます。 START&STOPとサンプルビットを検出するためのオーバーサンプリングで十分高速。Jack Ganssleによる記事「Bit Banging」は、あなたが噛むべきたくさんを与えます。
RS232波形の適切な説明については、BeyondLogicを参照してください。
考慮しなければならない電圧レベル(0 / + 5、-10V / + 10Vなど)などの他の問題があることに注意してください(「RS232レベルコンバーター」の論理を超えたセクションを参照)。上で説明した「回線を接続する」方法以外に、ハードウェアインターフェイスについて説明するのに十分な情報がシステムにありません。電圧レベルが一致していると仮定すると、通常、TXラインを2番目のレシーバー(スニファー)に「ティー」するのは問題ありませんが、TXに十分なドライブがない場合は、バッファー/ドライバーを挿入して、劣化からの信号。
通信が一度に一方向のみである場合(つまり、半二重通信)にできる巧妙なトリックがあります。両方の側が同時に(全二重)対話する場合は機能しませんが、それが一般的な「これを行う」「ここで応答する」「ここで行う」「ここで新しい応答する」タイプの通信の場合それはかなりうまくいきます。
UARTリンクはロジックハイ(1)レベルでトランスミッタのアイドル状態を使用するため、2入力ANDゲートを使用して、TXを両側からAND入力に接続します。ANDゲートの出力は、スニファーのUART(RXピン)への入力です。次に、デバイスBのTXラインを取得し、スニファーのI / Oポートに接続します。このピンがハイからローになったときに割り込みを生成するようにスニファーを構成します。
要約すると、デバイスA UART TX-> ANDゲート入力。デバイスB UART TX->他のANDゲート入力ANDスニファーGPIOピン。ANDゲートの出力->スニファーUART RXライン。
UART通信は、スタートビット、いくつかのデータビット、オプションのパリティビット、および1つ以上のストップビットで構成されます。アイドル状態は論理ハイ(1)であるため、すべてのバイトの開始は論理ロー(0)になり、スニファーの割り込みが発生します。スニファーがI / O割り込みを実行している間、UARTハードウェアはANDゲートからビットを収集します。UARTがストップビットを受信するまでに、I / O割り込みは長く行われ、UART RX割り込みが発生します。
IO変更割り込みルーチンは、「方向」変数を設定して、通信が「B-> A」方向であることを示します。スニファーのUART受信割り込みは、この「方向」変数を調べ、受信したばかりのバイトを適切なバッファーに書き込みます。次に、UART RX割り込みは、「方向」変数をデフォルトの「A-> B」状態に戻します。
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 */
}
このコードは明確にするために記述されており、必ずしも実際の状況で記述したものではありません。個人的には、「方向」を適切なFIFO構造へのポインタにしたいと思いますが、それは完全に別の課題です。:-)
デバイスAが話しているとき、I / Oラインは移動せず(デバイスBのUARTトランスミッターがアイドルであるため、論理「1」のまま)、UART RX割り込みがバイトを受信します。方向がA-> Bであることを確認してください、データをそのバッファに保存します。デバイスBが話しているとき、デバイスBがデータのシフトアウトを開始するとすぐにI / Oラインがローになり、I / O割り込みルーチンが方向を設定してデバイスBが話していることを示します。すべてのビットが収集された後、最終的にUART RX割り込みが発生し、I / O割り込みが方向レジスターの適切な設定を処理したため、受信したバイトは正しいバッファーに格納されます。
Presto:ビットバンピングUART通信なしで、単一のUARTとスニファーのI / Oラインでキャプチャされた2つのデバイス間の半二重通信。