When you are debugging an I2C bus on an ESP32 or setting GPIO port registers on an ATmega328P, you rarely have the luxury of doing base conversions in your head. You need the exact bit pattern or hex address immediately. The core 0-255 (8-bit) range is the most critical for microcontroller work, governing everything from PWM duty cycles to 7-bit I2C addresses and direct port manipulation.

The 8-Bit Hexadecimal Binary Decimal Table (0x00 to 0xFF)

How to read this table: This reference follows the base notation conventions standardized in ISO/IEC 80000-13 and adopted by C/C++ compilers. The 0x prefix denotes hexadecimal (base-16), and 0b denotes binary (base-2). The "Embedded Use Case" column highlights why that specific numeric boundary matters on the bench. These rows act as bookmark-friendly quick-jumps for the most queried values in microcontroller programming: the zero-state, powers of two (critical for bitwise masking), nibble boundaries, and the 8-bit maximum.

DecimalHexadecimalBinaryCommon Embedded Use Case
00x000b00000000GPIO LOW, PWM 0% duty, I2C NACK
10x010b00000001Bit 0 mask, LSB set
20x020b00000010Bit 1 mask
40x040b00000100Bit 2 mask
80x080b00001000Bit 3 mask
150x0F0b00001111Lower nibble mask (0b1111)
160x100b00010000Bit 4 mask, upper nibble start
310x1F0b000111115-bit max value (e.g., some DACs)
320x200b00100000Bit 5 mask, I2C address boundary
600x3C0b00111100SSD1306 OLED default I2C address
630x3F0b001111116-bit max value
640x400b01000000Bit 6 mask
1270x7F0b01111111Max 7-bit I2C address, 8-bit signed max
1280x800b10000000Bit 7 mask, MSB set, signed negative flag
2550xFF0b11111111GPIO HIGH, PWM 100% duty, 8-bit unsigned max
Bench Tip: If you need a value not listed here, break the hex byte into two nibbles. For example, 0xA5 is 0xA0 (160) + 0x05 (5) = 165 decimal. In binary, A is 1010 and 5 is 0101, making 0b10100101.

Which Column Applies to Your Microcontroller Task?

Beginners often memorize conversions without understanding which base is native to the hardware abstraction layer they are using. Here is how to choose the right column for your specific installation or codebase.

Base SystemBest Used ForHardware / Protocol ExamplesChoose This When...
HexadecimalMemory mapping, bus addresses, color codesI2C addresses (0x3C), SPI registers, RGB LEDs (#FF00FF)You are reading datasheets, configuring I2C/SPI peripherals, or defining color arrays.
BinaryBitwise masking, direct port manipulationGPIO PORT registers (PORTB), interrupt flags, pin statesYou need to set, clear, or toggle specific pins without affecting adjacent pins on the same register.
DecimalHuman-readable math, analog scaling, timingPWM duty cycles (0-255), ADC readings (0-1023), baud rates (115200)You are calculating physical outputs (voltage, RPM) or passing arguments to high-level API functions like analogWrite().

How Bit-Shifting and Protocols Modify the Base Value

In wire sizing, derating factors modify the base ampacity based on temperature and conduit fill. In digital logic and bus protocols, bit-shifting and protocol overhead modify the base numeric value you see in the table. If you do not account for these modifications, your bus will fail to initialize.

The most common trap for hobbyists is the 7-bit vs. 8-bit I2C address shift. The I2C specification defines addresses as 7 bits (ranging from 0x00 to 0x7F). However, the physical bus transmits 8 bits: the 7 address bits followed by a Read/Write (R/W) bit.

  • The Base Value: Your SSD1306 OLED datasheet lists the 7-bit address as 0x3C (Decimal 60, Binary 0b0111100).
  • The Modification (Write): To write to the display, the R/W bit is 0. The 7 bits shift left by one position (0x3C << 1), resulting in 0x78 (Decimal 120, Binary 0b11110000).
  • The Modification (Read): To read from the display, the R/W bit is 1. The shifted address gets a 1 added to the LSB, resulting in 0x79 (Decimal 121).
Why this matters: If you use a logic analyzer to sniff the I2C bus, the raw hex bytes on the wire will show 0x78, not 0x3C. Some libraries (like standard Arduino Wire) expect the 7-bit 0x3C and handle the shift internally. Others (like raw ESP-IDF I2C driver commands or certain Python smbus implementations) might require the shifted 8-bit value. Always check your ESP-IDF I2C documentation or library source code to see which base it expects.

Similarly, bitwise shifts modify values when configuring hardware registers. Setting the 5th bit of a register requires shifting a 1 left by 5 positions (1 << 5), which modifies the base decimal value of 1 into the decimal value of 32 (Hex 0x20). Mastering bitwise operators is mandatory for bare-metal register configuration.

What This Table Cannot Tell You (Endianness and Signed Integers)

While this hexadecimal binary decimal table perfectly maps 8-bit unsigned integers, it deliberately hides the complexities of multi-byte data and negative numbers. When you move beyond single-byte registers, the table falls short in three critical areas:

1. Endianness (Byte Order)

When reading a 16-bit or 24-bit sensor (like the BME280 pressure data or MPU6050 accelerometer axes) over I2C, you receive multiple bytes. The table cannot tell you which byte arrives first. Big-endian systems transmit the Most Significant Byte (MSB) first, while Little-endian systems (like the x86 architecture and many ARM Cortex-M implementations) transmit the Least Significant Byte (LSB) first. If you read 0x1A and 0x05 from a sensor, it could mean 0x1A05 (6661 decimal) or 0x051A (1306 decimal) depending entirely on the sensor's datasheet, not the math.

2. Two's Complement (Signed Integers)

The table lists 0xFF as 255. This is true for a uint8_t (unsigned 8-bit integer). But if your microcontroller variable is an int8_t (signed 8-bit integer), 0xFF represents -1. In two's complement, the Most Significant Bit (MSB) acts as a negative flag. Any hex value from 0x80 to 0xFF will be interpreted as a negative number (-128 to -1) if cast to a signed type. Always verify your variable types in C/C++. If you receive 0xFA from a temperature sensor and store it in a uint8_t, you get 250. If you cast it via (int8_t)0xFA, you correctly get -6.

3. Floating-Point Representation (IEEE 754)

You cannot use this table to decode floating-point numbers. If a sensor outputs a 32-bit float, the binary pattern does not map linearly to decimal values. The IEEE 754 standard divides the 32 bits into a sign bit, an 8-bit exponent, and a 23-bit fraction. A hex value of 0x41200000 translates to the decimal float 10.0, a relationship that requires a dedicated IEEE 754 converter, not a standard base-conversion table.

Keep this 8-bit table bookmarked for your daily GPIO, PWM, and I2C address debugging, but always defer to the specific component datasheet when handling multi-byte, signed, or floating-point data.