A hexadecimal sheet is a structured reference document that maps hex-encoded memory addresses, register values, or Intel HEX firmware records to their physical or logical locations in a microcontroller or peripheral chip. When you move from blinking an LED to writing custom bootloaders or debugging I2C EEPROMs, this sheet changes how your code physically maps to silicon, dictating exactly which memory sectors get overwritten and how peripheral registers are addressed. Beginners commonly confuse a hexadecimal sheet with a raw binary dump or an ASCII memory printout; unlike a raw binary file, a proper hex sheet includes structural metadata like checksums, record types, and extended addressing that tell the programmer exactly where the data belongs.
Anatomy of an Intel HEX Record: A Worked Numeric Example
If you open a compiled .hex firmware file in a text editor, you will see lines of ASCII characters. Each line is a record. Let's break down a real Intel HEX data record to see how the sheet translates to physical memory.
Consider this exact line from an AVR microcontroller firmware dump:
:10010000214601360121470136007EFE09D2190140
| Segment | Hex Value | Meaning & Numeric Breakdown |
|---|---|---|
| Start Code | : |
Colon indicates the start of a new record. |
| Byte Count | 10 |
Hex 10 = 16 bytes of actual data payload in this line. |
| Address | 0100 |
Hex 0100 = 256. This data writes to flash memory starting at address 0x0100. |
| Record Type | 00 |
00 means 'Data Record'. (01 is End of File, 04 is Extended Address). |
| Data Payload | 2146...1901 |
The 16 bytes of compiled machine code to be written to the flash sector. |
| Checksum | 40 |
Two's complement of the sum of all preceding bytes. Ensures no corruption during transfer. |
If your flashing tool (like AVRDUDE or esptool.py) reports a checksum error, it means the data payload was corrupted in transit, and the tool will halt to prevent writing garbage to your silicon.
Where You Meet This in Practice
You will pull up a hexadecimal sheet or hex dump viewer in three specific bench scenarios:
- Firmware Flashing & Bootloader Mods: When compiling C/C++ in an IDE like Keil, MPLAB, or PlatformIO, the output is often an Intel HEX file. You use the hex sheet to verify that your bootloader sits at the correct offset (e.g., 0x0000) and your application starts at the correct boundary (e.g., 0x1000).
- I2C and SPI Peripheral Debugging: Datasheets for sensors like the BME280 or MPU6050 provide 'Register Map' hex sheets. When your Arduino
Wire.read()returns garbage, you cross-reference the hex sheet to ensure you are reading from the correct 8-bit register address (like 0xF7 for BME280 pressure data). - EEPROM Data Logging: When storing configuration parameters in an external 24LC256 I2C EEPROM, you map out a hex sheet on paper or in a spreadsheet to define where your WiFi credentials, calibration offsets, and device IDs live so they don't overlap.
Real-World Scenario Walkthrough: Bricking an ESP32 via Bad Hex Offsets
Hex sheets aren't just theory; misreading them will brick your board. Here is a real bench failure involving an ESP32-WROOM-32.
1. The Setup
I was porting a custom motor-control firmware originally written for an STM32 (ARM Cortex-M) over to an ESP32. The original project output a firmware.hex file. Instead of letting the ESP-IDF build system generate standard .bin files, I attempted to flash the raw .hex file directly using a generic serial uploader, assuming the hex sheet's internal addresses would automatically map to the ESP32's SPI flash.
2. The Numbers
Looking at the top of the hex sheet, the first line was an Extended Linear Address record:
:020000040800F2
0800 payload shifts the base address to 0x08000000.
On an STM32, 0x08000000 is the standard start of internal flash memory. However, the ESP32 maps its SPI flash starting at 0x00000000 (or 0x3F400000 in the IRAM cache view).
3. The Outcome
The flash tool threw a warning about out-of-bounds addressing, but I forced the write. Upon resetting the ESP32, the serial monitor immediately spat out:
Guru Meditation Error: Core 0 panic'ed (IllegalInstruction). Exception was unhandled.
4. What Went Wrong
I trusted a hex sheet generated for an ARM architecture without translating the memory map. The Extended Linear Address record told the programmer to write the bootloader to an address space that doesn't exist on the ESP32's physical SPI flash. The ESP32 booted, found no valid bootloader at 0x1000 (the standard Espressif partition table offset), and panicked. The fix was to abandon the raw hex file, recompile using the ESP-IDF toolchain to generate architecture-specific .bin files, and flash using the standard partition offsets.
I2C and EEPROM Hex Sheets: Mapping Peripheral Registers
Beyond firmware, 'hex sheet' frequently refers to the register map tables found in silicon datasheets. Let's look at how to read one for a common I2C sensor.
Suppose you are wiring a Bosch BME280 temperature/humidity sensor to an Arduino Nano via I2C. The datasheet provides a massive hex sheet detailing the internal registers.
| Register Name | Hex Address | Read/Write | Function |
|---|---|---|---|
| chip_id | 0xD0 | R | Returns 0x60. Used to verify I2C wiring is correct. |
| reset | 0xE0 | W | Write 0xB6 to trigger a soft reset of the sensor. |
| ctrl_meas | 0xF4 | R/W | Sets oversampling for temp/pressure and selects sleep/normal mode. |
| press_msb | 0xF7 | R | Most significant byte of the raw pressure ADC reading. |
Bench Debugging Tip: If your I2C scanner finds the device at 0x76, but your code reads 0x00 from the chip_id register (0xD0), your hex sheet tells you exactly what to check next. Since 0xD0 is a read-only register that should always return 0x60 on power-up, a 0x00 reading means your I2C pull-up resistors are missing, your logic level is mismatched (3.3V vs 5V), or the chip is stuck in a sleep state. You don't need an oscilloscope to figure this out; the hex sheet gives you the diagnostic baseline.
Frequently Asked Questions
Can I just convert a .hex file to .bin and flash it?
Yes, tools like objcopy or Hex2Bin can strip the metadata and convert Intel HEX to raw binary. However, you must manually specify the base address offset during conversion. If the hex sheet contains multiple disjointed memory blocks (like separate bootloader and app partitions), a flat binary conversion will either pad the gaps with 0xFF (wasting flash space) or collapse the blocks together, ruining the memory map.
Why do hex sheets use two's complement for checksums?
Two's complement allows the flashing tool to verify the line by simply adding all the bytes together (including the checksum). If the line is uncorrupted, the lowest 8 bits of the sum will always equal exactly 0x00. It is a computationally cheap way for 8-bit microcontrollers to verify data integrity on the fly.
What is the difference between an Intel HEX sheet and a Motorola S-Record?
Both serve the same purpose—mapping hex data to memory addresses—but they use different syntax. Intel HEX uses a leading colon (:) and ASCII hex pairs, while Motorola S-Records (SREC) use a leading S followed by a record type number (e.g., S1 for 16-bit address data). Intel HEX is vastly more common in modern hobbyist and ARM/AVR ecosystems.






