MAX7219 tube clock/How the chip thinks/07. Sixteen bits, one register
How the chip thinks · 07 of 12

Sixteen bits, one register

Every message to a MAX7219 is the same shape: sixteen bits, of which four are ignored, four are an address and eight are data. Then CS goes high and the chip acts on it. Nothing at all happens before that edge, which explains one of the stranger faults on this board.

One frame

Sixteen bits, then one rising edge
0/16 bits
Which write
Word sent
0x0304
As bits
00000011 00000100
Register
Digit 2
The chip has no idea what it is receiving yet. Every rising CLK edge pushes one more bit into a plain sixteen-bit shift register, address bits and data bits alike, and the chip does not look at any of them. The top four bits are genuinely ignored — send whatever is convenient.

Press Clock it in and watch what the display does, which is nothing, until the very last step.

Sixteen rising clock edges push sixteen bits into an ordinary shift register inside the chip. Most significant bit first. The chip is not interpreting any of them as they arrive — it does not know whether it is receiving an address or data, and it does not care.

BitsWhat they are
D15–D12Ignored. Send zeros.
D11–D8The register address, 0x0 to 0xF
D7–D0The data byte

Then CS rises, and on that edge the sixteen bits move into whichever register the address named. That is the entire protocol.

Why the edge matters

Because everything before it is reversible and nothing after it is.

Two consequences follow, and both of them show up as real faults:

CS has to rise after the sixteenth clock edge and before the next one. Leave it and the frame is lost — the seventeenth clock pushes the first bit out the other end of the shift register and the word is scrambled. Every library gets this right; hand-written bit-banging sometimes does not.

CS held low gives you a display that lags. Each frame you send sits in the shift register, uncommitted, until the following frame's clocks push it into place. So the display shows the previous message, always, and looks like a timing bug in your sketch. It is a wiring problem: something else is holding that pin, or it was never connected.

The fourteen registers

Eight of them are the digits. The other six are the whole of the chip's behaviour.

AddressRegisterWhat it does
0x00No-opNothing. What you send to a chip in a chain you are not addressing.
0x010x08Digit 0–7One byte each. This is the display.
0x09Decode modeOne bit per digit: use the built-in font, or take the bits raw.
0x0AIntensityBrightness, 0 to 15.
0x0BScan limitHow many digits get a turn, 0 to 7 meaning 1 to 8.
0x0CShutdown0 blanks and stops the scan. The power-up value.
0x0FDisplay test1 lights everything, overriding all of the above.

Two things worth noticing in that table. The digit registers are one-based while the digits are zero-based — digit 0 lives at address 0x01 — which is a transposition waiting to happen. And 0x0F, display test, ignores shutdown, ignores intensity and ignores every digit byte, which makes it the single most useful diagnostic on the board: one write, and either all sixty-four LEDs light or your wiring is wrong.

Speed is not the problem

The minimum clock period is 100 ns, so the interface will take 10 MHz. Nothing in the Arduino world sends it that fast — LedControl bit-bangs with shiftOut and manages a few hundred kilohertz on an Uno — and it does not matter, because eight digits is sixteen bytes and a clock update is two or three of them.

Which is why none of the three signal pins has to be a special pin. There is no peripheral to match, no baud rate to agree on, and no minimum speed below which the chip times out. Any three GPIOs.

When it does not work

The display is always one write behind

CS is not being taken high between frames. The shift register keeps accepting bits whatever CS is doing, and only the rising edge moves them into a real register — so with CS held low each frame appears when the next one pushes it through. Check nothing else on your board is driving that pin, and that you have not wired CS to a pin your board uses for something at boot.

How fast can I clock it?

10 MHz, from the 100 ns minimum clock period. No Arduino library gets close: LedControl bit-bangs with shiftOut and manages a few hundred kilohertz on an Uno. Speed is never the constraint on this board, which is why any three GPIO pins will do.

Can I use hardware SPI instead of LedControl?

Yes. The frame is MSB first, data sampled on the rising clock edge, which is SPI mode 0, and CS is an ordinary chip select you assert low around the sixteen bits. The MAX7221 is the variant Maxim made properly SPI-compatible, but the MAX7219 works this way in practice on every board people have tried it on.

What are the top four bits for?

Nothing. D15 to D12 are genuinely don't-care and the chip discards them, so send zeros and stop worrying about them. They exist because the address field only needs four bits and the frame is a round sixteen.

I sent a digit register and the wrong digit changed

The digit registers are addresses 0x01 to 0x08 for digits 0 to 7, so they are one-based while the digit numbering is zero-based. Digit 0 is register 0x01. Address 0x00 is the no-op register and writing a digit's worth of data there does nothing at all.

Where this goes next

The chip has a font built in and will also let you drive the segments yourself — and the raw bit order is backwards from every other display in the shop.

Decode, or no decode

Edit this page — content/books/max7219-tube-clock/sixteen-bits-one-register.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

MAX7219 Vintage Tube LED Clock Kit

Loading discussions…

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Modules and blocks on the forum