双方向信号について(トライステートバッファ)

双方向信号の扱いについて、何となくで使っていた部分があったので整理しました。

双方向信号とは

一定の条件に従い、信号の入出力方向が変化する信号です。I2Cのように少ない信号線で通信を実現するような場合に使用されます。

トライステートバッファ

双方向信号を実現するための回路です。LowとHighに加えて、ハイインピーダンスが出力可能なため、トライ(=3)ステートと呼ばれます。

論理回路

enが1の場合は入力がそのまま出力されるため、LowとHighを出力可能です。enを0とすると出力が切り離されて未接続となるため、出力としてはハイインピーダンスとなります。

トライステート

VHDL

トライステートバッファのVHDLでの記述方法です。

Y <= X when (en = '1') else 'Z';

双方向バッファ

双方向信号を実現するための回路はトライステートバッファを組み合わせて実現し、双方向バッファと呼ばれます。

論理回路

X側を内部回路側、Y側を外部ピン側と仮定します。その場合、左図が信号を出力として扱っている状態です。逆に右図では外部ピンへの出力をハイインピーダンスとし、外部ピンを内部回路へ接続します。これにより信号を入力として扱えるようにしています。

双方向バッファ

VHDL

双方向バッファはトライステートバッファを使用して実現するため、出力方向の記述はトライステートバッファそのままとなります。ただ、外部ピンへ接続される信号を入力信号としても使用可能となります。

Y : inout std_logic; -- Entity Portでの宣言にて"inout"を使用

Y <= X when (en = '1') else 'Z';
internal_signal <= Y; -- 外部ピンからの入力として内部にて使用可能

双方向バッファとプルアップ

今回双方向バッファについて見直そうと思ったきっかけが、次のような回路を見かけたからでした。
「双方向バッファの制御時に、出力をLowに駆動する場合はLowに制御。そうでない場合にはハイインピーダンスにする」
これだとHighに駆動できないじゃないか…、と思ったのですが、双方向ピンとして扱う信号をプルアップしておけばいいんですね。下図のような感じです。
双方向バッファ High駆動
この場合左右どちらも入力として信号を扱っていますが、プルアップによりHighが入力されることになります。次に左側がLowに駆動した場合を考えます。
双方向バッファ Low駆動
Lowに駆動するときだけ左側を出力信号とすることで、右側の回路をLowに駆動できます。

この制御方法の良いところは、出力ピンをHighへ駆動しないので、High出力とLow出力がぶつかってしまう状況が発生しない点です。つまり制御を間違えて左右両方を出力ピンとしてしまっても、ショートすることはなくなります。

もちろんGNDレベルが左右で同じとは限らないので出力ピンの衝突は避けないといけないのは変わらないのですが、より安全な回路となるんですね。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする