Binary-coded decimal (BCD) is a digital encoding method where each individual decimal digit from 0 to 9 is represented by its own distinct four-bit binary sequence. While a microcontroller natively calculates in pure base-2 binary, BCD acts as a bridge between human-readable base-10 numbers and digital logic. This encoding fundamentally changes how you wire human-machine interfaces—like digital readouts and thumbwheel switches—trading a slight waste of bit states for massively simplified display hardware and straightforward base-10 parsing.

What Binary-Coded Decimal Actually Is (and Isn't)

In standard 8421 BCD, every decimal digit gets its own 4-bit block (a nibble). The bits represent the weights 8, 4, 2, and 1. Because we only need to represent the numbers 0 through 9, the binary states from 1010 (decimal 10) through 1111 (decimal 15) are considered invalid or "don't care" states.

The most common mistake hobbyists make is confusing BCD with pure binary. In pure binary, an 8-bit bus can represent any number from 0 to 255. In BCD, that same 8-bit bus is split into two nibbles, meaning it can only represent decimal numbers from 00 to 99.

The Wasted States Trade-Off: Out of the 16 possible states in a 4-bit nibble, BCD only uses 10. This means 37.5% of your bit combinations are "wasted." We accept this inefficiency because it eliminates the need for complex binary-to-decimal math when driving displays or reading human-input dials.
Decimal ValuePure Binary (8-bit)BCD (8-bit / 2 Nibbles)
050000 01010000 0101
090000 10010000 1001
100000 10100001 0000
150000 11110001 0101
420010 10100100 0010

The Math: A Worked Numeric Example

Let's convert the decimal number 254 to see the structural difference on a workbench.

  1. Pure Binary Conversion: You divide the entire number by powers of 2. The 8-bit binary representation for 254 is 11111110.
  2. BCD Conversion: You ignore the total value and look at each digit individually.
    • The digit 2 becomes 0010
    • The digit 5 becomes 0101
    • The digit 4 becomes 0100
  3. The Result: The BCD representation is 0010 0101 0100. Notice that BCD requires 12 bits to represent a number that pure binary handles in just 8 bits.

If you were to feed the pure binary string 11111110 into a BCD decoder chip, it would fail to display "254" because the chip expects nibble boundaries, not a continuous base-2 stream.

Where You Meet BCD in Practice

You will rarely write BCD math loops in modern firmware, but you will constantly encounter BCD in hardware peripherals and legacy interfaces.

Real-Time Clocks (RTCs)

Integrated circuits like the Maxim/Analog Devices DS3231 store time internally in BCD format. If the time is 23:59, the minutes register holds 0101 1001 (59 in BCD), not 0011 1011 (59 in pure binary). This allows the chip's internal divider logic to roll over from 9 to 0 and carry a bit to the tens place, perfectly mimicking base-10 timekeeping without requiring a silicon-heavy binary divider.

Thumbwheel Switches

Industrial and avionics panels often use hardware thumbwheel switches. Behind the dial, a PCB wiper physically grounds specific pins to output a hardwired BCD code. You read these four pins directly into your microcontroller's GPIO, requiring no analog-to-digital conversion.

7-Segment Display Decoders

Instead of using 7 microcontroller pins to draw the shape of a number, you use 4 pins to send the BCD value to a decoder IC like the 74LS47 (common anode) or CD4511 (common cathode). The chip handles the segment routing.

Bench Scenario: Driving a 7-Segment Display (And What Goes Wrong)

Let's walk through a real bench setup using a Texas Instruments CD4511B BCD-to-7-segment latch/decoder driving a standard 5641AH common-cathode LED display.

The Setup

We wire four DIP switches to the CD4511 inputs (A, B, C, D). We connect 330Ω current-limiting resistors from the chip's segment outputs (a-g) to the display. Pin 3 (Lamp Test), Pin 4 (Blanking), and Pin 5 (Store) are tied HIGH to VCC (5V) to enable normal decoding mode.

The Numbers and Outcome

We flip the DIP switches to 0111 (Switches A, B, C closed to GND; Switch D open to 5V). The CD4511 reads this valid BCD state and illuminates segments a, b, c, d, e, and f. The display correctly shows the number 7.

What Went Wrong: Two Common Failure Modes

Failure 1: Invalid BCD States. A hobbyist assumes the CD4511 acts like a pure hex-to-7-segment decoder. They flip the switches to 1100 (decimal 12 in pure binary). Because 12 is outside the 0-9 BCD range, the CD4511's internal logic recognizes an invalid state. According to the BCD decoding truth tables, the chip responds by blanking the display entirely. The display goes dark, leading the builder to assume the LED is burned out.

Failure 2: Floating CMOS Inputs. The builder wires the DIP switches to VCC to represent a "1", but forgets to wire pull-down resistors to GND for the "0" state. When a switch is open, the CD4511's high-impedance CMOS inputs are left floating. They act as antennas, picking up 60Hz electromagnetic noise from nearby mains wiring. The display violently flickers between random numbers as the input pins randomly cross the logic threshold voltage.

The Fix: Always use 10kΩ pull-down resistors on every BCD input line when using mechanical switches. If your microcontroller is driving the BCD lines, ensure your GPIO pins are set to push-pull output mode, never open-drain, unless you have external pull-ups.

Frequently Asked Questions

What is the difference between packed and unpacked BCD?

In packed BCD, two decimal digits are squeezed into a single 8-bit byte (one digit in the upper nibble, one in the lower nibble). This is how the DS3231 RTC stores data to save memory. In unpacked BCD, each digit takes up a full 8-bit byte, with the upper nibble padded with zeros (e.g., decimal 5 is stored as 0000 0101). Unpacked BCD wastes space but is faster for simple microcontrollers to process because it avoids bit-shifting operations.

Why not just use pure binary and do the math in software?

For modern 32-bit ARM Cortex microcontrollers, doing binary-to-decimal conversion in software takes negligible clock cycles. However, in hardware-constrained environments, FPGAs, or when interfacing with legacy 7400-series logic chips, offloading the base-10 translation to a dedicated BCD decoder chip saves GPIO pins and simplifies the PCB layout. Furthermore, doing base-10 math (like adding seconds to minutes) in pure binary requires complex division and modulo operations, whereas BCD addition just requires a simple "add 6" correction rule when a nibble exceeds 9.

Can BCD represent negative numbers or decimals?

Standard 8421 BCD does not natively support signs or decimal points. To represent negative numbers, systems typically use a dedicated 5th bit or a separate sign nibble (like 1100 for '+' and 1101 for '-' in IBM mainframe architectures). Decimal points are handled purely at the hardware display level by routing a separate GPIO pin to the display's DP (decimal point) LED segment, completely bypassing the BCD encoding logic.