Back to blog

An advanced guide to communication protocols in microcontrollers

Automotive

06 / 02 / 2026

An advanced guide to communication protocols in microcontrollers

Key Takeaways

  • Distance and node count settle the protocol choice long before throughput does, so size the physical layer first and let firmware follow.
  • SPI, UART, I2C and CAN each trade one resource for another, and the right pick is the one whose cost your design can absorb.
  • Protocol boundaries set early keep an embedded controller portable across benches and toolchains instead of locking it to one board.

Choosing a communication protocol for a microcontroller is a hardware decision you make once and live with for the life of the product.

Pin count, cable length, node count and error handling all move at once, and getting them wrong shows up as intermittent faults nobody can reproduce. A premium vehicle now carries roughly 150 electronic control units, each one a microcontroller that has to exchange data without dropping a frame.

SPI, UART, I2C and CAN survive because each solves a different problem. SPI buys throughput with pins, I2C buys pins back at the cost of speed, and CAN spends silicon to stay alive across a noisy chassis. Match the protocol to the constraint that actually binds your design and the firmware above it gets simpler.

How serial communication works inside a microcontroller system

Serial communication moves data one bit at a time across a few wires, trading parallel bandwidth for pins and board space. Every protocol on a microcontroller layers rules on that idea, covering clocking, device selection and error handling.

A typical Cortex-M part gives you several USART blocks, two or three SPI blocks, a couple of I2C blocks and often a CAN controller. They share pins through a multiplexer, so the protocol you pick for a sensor decides which pins remain.

Five properties decide how a bus behaves once the board is populated.

  • Clocking, since a synchronous bus carries a clock line while an asynchronous one assumes a preset bit rate.
  • Addressing, which sets how many devices share the wires.
  • Topology, covering point-to-point links against multi-drop buses that span a chassis.
  • Electrical reach, since single ended signals fade over long runs while differential pairs survive them.
  • Error handling, meaning what the silicon does when a checksum fails.

Get these five straight before data rates enter the discussion. No firmware will fix a physical layer that wasn’t sized for the job.

Why SPI wins when raw throughput matters most

SPI is a synchronous full duplex bus that runs at tens of megahertz because the controller supplies the clock and no addressing sits inside the frame. Four wires carry the clock, two data lines and a chip select, and every peripheral costs another select pin.

Display work shows the tradeoff. A 320 by 240 colour TFT at 30 frames per second needs megabytes per second of pixel data, which SPI moves comfortably at 40 MHz while I2C at 400 kHz would need minutes per frame.

SPI gives up discipline inside the protocol itself. It defines no acknowledgement and no recovery, so a peripheral that misses a clock edge quietly returns garbage and your firmware has to catch it with its own CRC. Trace length matters too, since a 40 MHz clock across 30 centimetres of ribbon cable rings badly enough to corrupt data.

“It defines no acknowledgement and no recovery, so a peripheral that misses a clock edge quietly returns garbage and your firmware has to catch it with its own CRC.”

How UART handles point-to-point links without a clock

UART connects exactly two devices over two wires with no shared clock, so both ends have to agree on a bit rate beforehand. That simplicity is why it’s the first interface engineers bring up on new hardware and the last one they remove.

Almost every module you buy speaks it. A GNSS receiver streams position sentences at 9600 baud, and a debug console over a USB bridge gives you readable output minutes after powering a fresh board.

The limits appear the moment you add a third device. UART carries no addressing, so scaling past a single link means RS-485 transceivers and an addressing scheme you now maintain. Clock accuracy is the other constraint, since the receiver samples the middle of each bit and tolerates only about 2% of drift, which is why an internal RC oscillator causes trouble at higher rates and a crystal doesn’t.

Why I2C suits sensor networks with limited pin counts

I2C puts many devices on two wires by giving each a 7 bit address the controller uses to select it. Open drain outputs with pull-up resistors let any device hold a line low, which is how acknowledgement and clock stretching work without extra pins.

Sensor clusters are where this pays for itself. A handheld instrument might carry a temperature sensor, an accelerometer, a small EEPROM and a power monitor on the same two pins.

Two failure modes come with that convenience. Identical parts often ship with the same fixed address, so three of the same pressure sensor need a multiplexer, and learning that at the prototype stage is expensive. Bus capacitance is the other ceiling, since the specification caps a standard bus at 400 pF and crowded boards push past it, at which point 400 kHz stops working.

How CAN keeps distributed controllers reliable under electrical noise

How CAN keeps distributed controllers reliable under electrical noise

CAN carries messages on a differential twisted pair so electrical noise hits both wires equally and cancels at the receiver. Nodes aren’t addressed individually. Each message carries an identifier that also sets its priority, and the hardware resolves collisions without losing the winning frame.

That design has proven itself at volume, with more than 2 billion CAN nodes sold every year across vehicles and industrial machinery. An electric drivetrain shows why. Battery management, the inverter, the charger and the instrument cluster sit metres apart on one twisted pair, and a fault message from the battery wins arbitration over a routine temperature update.

The silicon does work firmware would otherwise carry. CAN controllers handle CRC checks, acknowledgement and retransmission, and a node that keeps failing takes itself off the bus. You pay in payload size and planning, since classic frames carry 8 bytes and CAN FD raises that to 64 bytes, and every identifier has to be allocated before anyone writes firmware.

Choosing the right protocol for your application constraints

Start with the physical constraint you can’t negotiate, usually distance or node count, and only then look at throughput. A link crossing 2 metres of cable inside a machine rules out SPI and I2C before speed enters the discussion.

Protocol and wiring Where it fits best What it costs you
SPI, four wires plus a select line per device On-board links to displays, flash and high rate converters. Pin count grows with every peripheral and nothing is checked.
UART, two wires between two devices Debug consoles, GNSS receivers and modems feeding one listener. Nothing scales past two nodes without transceivers and custom addressing.
I2C, two shared wires with pull-up resistors Clusters of low rate sensors and configuration memories. Address clashes and bus capacitance cap device count and clock rate.
CAN, one differential twisted pair across a chassis Controllers metres apart in vehicles and machinery. Small payloads and identifier planning across the whole network.

Mixed designs are the norm. A motor controller will read its position sensor over SPI, configure a power monitor over I2C, expose a UART for service technicians and report to the vehicle over CAN. Teams at OPAL-RT meet the same mix when embedded controller code moves from a bench prototype onto lab hardware, where toolchain compatibility keeps the port from becoming a rewrite.

Common questions about microcontroller communication protocols answered clearly

What is the main difference between SPI and I2C?

The main difference between SPI and I2C is that SPI trades pins for speed while I2C trades speed for pins. SPI needs a select line per peripheral at tens of megahertz, and I2C shares two wires across many addressed devices up to 3.4 MHz.

Is CAN worth using on a single circuit board?

Rarely. CAN earns its cost when nodes sit metres apart under electrical noise, and on one board SPI or I2C moves the same data with less silicon. The exception is a board joining an existing CAN network.

Which protocol should you bring up first on new hardware?

UART, almost always. A working serial console gives you printed output to debug everything else, and it needs only two pins and a correct clock setting.

Where protocol discipline pays off across a product lifecycle

Protocol choices age badly when they’re made for the prototype instead of the product. Teams that pick a bus on pin availability alone spend years adding multiplexers, retry logic and shielding to prop up a design a differential pair would have carried.

The engineers who don’t have this problem treat the bus as part of the system architecture. They count nodes and cable lengths before selecting parts, budget for the pins that select lines consume, and write down the identifier map before firmware starts. None of that is glamorous, and all of it is cheaper than chasing an intermittent fault on a production line.

OPAL-RT sees the payoff in how cleanly embedded controller work moves between benches, since a design with clear protocol boundaries ports across toolchains without anyone rewriting the interface layer. Sound protocol selection is quiet engineering, showing up as boards that come up on the first try and buses that stay reliable long after the people who chose them move on.

“The engineers who don’t have this problem treat the bus as part of the system architecture.”