CAN Frame Format
Embedded → CAN Bus + Automotive
One wire pair, every ECU, one packet shape
Every module in a car — engine controller, ABS, infotainment, airbag — shares the same two-wire differential bus (CAN_H/CAN_L) and speaks the same packet format. There's no destination address in a CAN frame: every node receives every frame and decides for itself, by identifier, whether to care.
The classic (2.0A / standard) data frame, field by field
A standard CAN 2.0A data frame is built from these fields, transmitted MSB-first with no byte-alignment padding between them:
| Field | Width | Role |
|---|---|---|
| SOF | 1 bit | Start of Frame — dominant (0), tells every node a transmission is beginning |
| Arbitration ID | 11 bits | Identifier — lower value wins bus arbitration (see the arbitration lesson) |
| RTR | 1 bit | Remote Transmission Request — 0 for a data frame, 1 for a remote (request-only) frame |
| Control (incl. DLC) | 6 bits | Reserved bits + 4-bit Data Length Code, 0-8 |
| Data | 0-8 bytes | The payload itself — up to 64 bits, the actual signal values |
| CRC | 15 bits + delimiter | Cyclic redundancy check over SOF through data, catches bit errors |
| ACK | 1 bit + delimiter | Transmitter sends recessive; ANY receiver that got a valid CRC pulls it dominant |
| EOF | 7 bits | End of Frame — 7 recessive bits, a gap no other field ever produces |
Notice the ACK field: the transmitting node never asserts its own ACK bit. It sends it recessive (1) and listens — if the frame's CRC checked out on anyother live node, that node pulls the line dominant (0) for that one bit. A transmitter seeing its own ACK bit still recessive means nobody else heard the frame correctly — a real fault condition, since every powered, correctly-wired node ACKs every valid frame regardless of whether it “wants” that ID.
Standard (11-bit) vs extended (29-bit) identifiers
CAN 2.0A uses an 11-bit identifier (2,048 possible IDs). CAN 2.0B extends this to 29 bits (over 536 million IDs) via an IDE (Identifier Extension) bit plus 18 more identifier bits. Automotive OEMs mix both on the same bus — powertrain/chassis signals are usually standard 11-bit IDs (lower IDs, higher arbitration priority); 29-bit extended IDs show up more in diagnostic/J1939-style truck and industrial protocols, where the wider ID space encodes a source address and PGN directly into the identifier.
Reading it in code
On an STM32 with an MCP2551/2515 transceiver, the frame fields map directly onto the peripheral's mailbox/FIFO registers — the CAN controller assembles the bitstream in hardware. What you write is just the logical fields:
CAN_TxHeaderTypeDef tx;
tx.StdId = 0x123; // 11-bit arbitration ID
tx.IDE = CAN_ID_STD; // standard, not extended
tx.RTR = CAN_RTR_DATA; // data frame, not a remote request
tx.DLC = 2; // 2 data bytes follow
uint8_t data[2] = { 'H', 'I' };
HAL_CAN_AddTxMessage(&hcan, &tx, data, &mailbox);
// SOF/CRC/ACK/EOF are all generated and checked by the CAN peripheral in hardwarePractice
Completion saves automatically after you read through to the end.
Next lesson →