Loading header...

Tri-State Buses - Sharing Wires Without Contention

Address decoding chooses which chip should respond. Tri-state outputs make sure every other chip electrically gets out of the way.

A normal digital output has two driven states: logic low and logic high. A tri-state output adds a third state: high impedance, usually written Hi-Z or Z. In Hi-Z, the output is effectively disconnected from the bus. It is neither pulling the wire up nor pulling it down.

Learning Objectives

By the end of this lesson, you should be able to:

  • explain the difference between logic 0, logic 1, and Hi-Z;
  • describe how chip-select and output-enable signals control shared bus drivers;
  • identify bus contention and floating-bus conditions;
  • connect tri-state behavior to memory buses and GPIO direction control;
  • apply practical timing and debugging checks for shared parallel buses.

Why Two-State Outputs Cannot Share a Wire

If two ordinary outputs drive the same wire, four cases are possible:

Driver A Driver B Result
low low valid low
high high valid high
low high contention, high current
high low contention, high current

The last two rows are not just "bad data." They create a low-resistance path between supply and ground through output transistors. That can cause heat, voltage collapse, data corruption, and permanent damage.

flowchart TB ROM["ROM output drives high"] --> D0["Shared D0 wire"] RAM["RAM output drives low"] --> D0 D0 --> CPU["CPU input"] D0 --> BAD["Contention current"]

A shared bus needs a way for unselected devices to become electrically silent.

The Third State: High Impedance

A tri-state buffer has a data input, an output, and an enable input.

flowchart LR DATA["Internal data"] --> BUF["Tri-state buffer"] EN["Output enable"] --> BUF BUF --> BUS["Shared bus line"]

When output enable is active, the buffer drives 0 or 1. When output enable is inactive, the buffer goes Hi-Z.

Enable Data input Output
inactive 0 or 1 Hi-Z
active 0 driven low
active 1 driven high

Hi-Z is not a third logic value stored by the CPU. It is an electrical state where the output driver is disconnected. If no other device drives the wire, the bus may float.

How Chip Select and Output Enable Work Together

Memory chips often use both chip-select and output-enable pins:

  • CS_N selects the chip package;
  • OE_N enables output drivers during reads;
  • WE_N enables writes during write cycles.

For a read from ROM, a simplified enable expression is:

ROM_drives_bus when ROM_CS_N = 0 and RD_N = 0 and OE_N = 0

For all other devices, at least one of those conditions must keep their outputs disabled.

flowchart LR ADDR["Address decoder"] --> CS["Device CS_N"] RD["RD_N"] --> OELOGIC["Output enable logic"] CS --> OELOGIC OELOGIC --> TBUF["Data bus tri-state drivers"] TBUF --> DBUS["D7..D0 shared bus"]

The decoder gives exclusivity. The tri-state buffers enforce electrical silence.

Bus State Timing

title "Illustrative tri-state read cycles"
time start=0 end=12 unit=us divisions=12

CSROM: pulse label="ROM CS_N active low" high=1 low=0 at=2 width=3 unit=logic color=#2563eb
CSRAM: pulse label="RAM CS_N active low" high=1 low=0 at=7 width=3 unit=logic color=#16a34a
RD: pulse label="RD_N active low" high=1 low=0 at=2.5 width=2.2 unit=logic color=#7c3aed
BUS: pulse label="Data valid windows" low=0 high=1 at=3 width=1.8 unit=valid color=#f59e0b
marker ROMDATA at=3 label="ROM drives"
marker FLOAT1 at=5.5 label="Hi-Z gap"
marker RAMDATA at=8 label="RAM drives"

This waveform is explanatory. In a real timing diagram, the bus would have setup, access, hold, and turn-off timing from the device datasheets.

Floating Buses and Pull Resistors

If every connected output is Hi-Z, the bus is floating. A floating digital input may read 0, 1, or a previous-looking value depending on leakage, capacitance, noise, and input thresholds.

Designs sometimes add weak pull-up or pull-down resistors so an otherwise idle bus has a defined default state. Pull resistors do not replace output-enable discipline. They are weak by design; a real driver easily overrides them.

GPIO Direction Is Tri-State Control

The same idea appears in a microcontroller GPIO pin.

GPIO mode Output driver Pin behavior
input Hi-Z external circuit drives the pin
output low enabled low driver MCU pulls pin low
output high enabled high driver MCU pulls pin high
input with pull-up Hi-Z plus weak pull-up default high unless external circuit pulls low

The data register controls the value. The direction register controls whether the output driver is enabled. That direction bit is a small tri-state control.

Worked Example: Safe Shared Data Bus

Suppose ROM and RAM share D7..D0.

Safe read from ROM:

ROM_CS_N = 0
RAM_CS_N = 1
RD_N = 0
WE_N = 1

Result: ROM output drivers are enabled; RAM output drivers are Hi-Z.

Unsafe case:

ROM_CS_N = 0
RAM_CS_N = 0
RD_N = 0

Result: both devices may drive D7..D0. If any bit differs, that data line has bus contention.

Practical Checks

  • Confirm only one device can have output drivers enabled at a time.
  • Check active-low names and polarities in both schematic and firmware.
  • Verify decoder outputs during every address range, including reserved ranges.
  • Account for bus turn-around time when direction changes.
  • Add idle pulls only when the bus or input specification requires a defined idle state.
  • Use an oscilloscope or logic analyzer to detect overlapping enables, slow edges, or unexpected floating levels.
  • Check device absolute maximum ratings if contention may have occurred.

Common Mistakes

  • Thinking Hi-Z means logic 0. It means disconnected.
  • Assuming chip-select alone disables outputs when the datasheet also requires OE_N.
  • Enabling two peripherals on the same bus during reset or boot.
  • Ignoring bus turn-off time before another device starts driving.
  • Leaving input pins floating and then treating random readings as software bugs.
  • Using pull resistors that are too strong, causing unnecessary current when the bus is driven.

Summary

Tri-state outputs let shared buses work. A selected device drives 0 or 1; unselected devices go Hi-Z and stop affecting the wire. Correct designs combine address decoding, chip-select, output-enable, write-enable, and timing margins so that exactly one device drives the data bus during a read, and no device fights another.

Further Reading

  • Texas Instruments, Understanding and Interpreting Standard-Logic Data Sheets, output enable and high-impedance behavior.
  • Nexperia, 74HC245 Octal Bus Transceiver datasheet, tri-state bus transceiver timing.
  • Microchip, AVR GPIO port documentation, DDR, PORT, and PIN register behavior.
  • Wakerly, Digital Design, buses, tri-state outputs, and contention.

Mind Map

mindmap root((Tri-State Buses)) Core concept Drive low Drive high Hi Z disconnect Share one wire Bus safety One driver at a time Others disabled Avoid contention current Floating needs care Control signals CS_N selects chip OE_N enables read drivers WE_N controls writes Direction bit for GPIO Timing checks Enable overlap Turn off delay Access time Hold time Practical fixes Complete decode Weak pulls when needed Logic analyzer check Reset default states Common mistakes Hi Z as zero Wrong active low polarity Two drivers enabled Floating input ignored

-> Opcode Tables