I am trying to understand a HEX file I compiled with Microchip MPLAB X IDE using the Microchip MPLAB XC16 Compiler.

Concerning the MCU, I am targeting the PIC24EP512GU814. However the scope of this question should at least apply to all PIC24 MCUs.

To compile the example HEX below, during the "New Project" wizard, I selected Samples > Microchip Embedded > PIC24 C Template and picked the XC16_24EP512GU814 configuration.

According to the PIC24EP / dsPIC33 Datasheet section 4.1.1 page 48, The memory is segmented into 16-bit words, such that each position (0x0000, 0x0001, ...) contains 16 bits. On the same page of the datasheet, program instructions are said to be 24-bit and span 2 words, such that the most significant byte of the most significant word is zero (00000000b).

This does not appear to be consistent with the compiled HEX file. Here are the first 5 lines of the file, numbered and with the different parts spaced out according to the Intel HEX specifications.

1. :02 0000 04 0000                             fa
2. :08 0000 00 0002040000000000                 f2
3. :02 0000 04 0000                             fa
4. :10 0008 00 c8020000ce020000e4020000d4020000 92
5. :10 0018 00 da020000e8020000ec020000e0020000 42

Consider lines 4 and 5. The first field correctly counts 0x10 (16) bytes in the data field. However, the second field which denotes location in the memory jumps from 0x0008 to 0x0018, or 0x0010 (16) positions.

From my interpretation, this means that this particular HEX file is 8-bit instead of 16-bit because each position is occupied by one byte.

  • Is there a way to make the compiler output a 16-bit file?
  • Is this file still valid for a 16-bit MCU? How can I interpret the HEX file so that I can manually flash the MCU?

3 Answers 3


Intel HEX files are always byte-addressed. This does not mean they can't handle information for other word sizes, only that there needs to be a convention about how those words are mapped to the bytes of the HEX file.

Just like with all the other non-byte addressed PICs (PIC 10, 12, and 16), the addresses are doubled in the HEX file. PIC programmer software knows this and interprets the HEX file addresses accordingly. This is of course all well documented in the programming spec for whatever part you want to program.

You say you want to make your own programmer. That's fine as long as you understand this will take way more time and frustration than just getting a known working one. If the point is the experience and learning of making your own, then fine, but otherwise go buy one.

If you really do want to make your own, you should look at the code for my PIC programmers. All the host code and firmware is open and available in the Development Software release at http://www.embedinc.com/picprg/sw.htm. By looking thru the host source code, you can see how there are flags indicating whether HEX file addresses are doubled for various parts of the PIC's memory.

If you make your programmer compatible with my PIC programmers protocol, then you can make use of all my host-side tools. This could be very helpful when bringing up your system since you have known working code on the other side. The protocol spec may look intimidating at first, but look carefully and you will see much of it is optional, especially if you plan to only support a single PIC.

  • \$\begingroup\$ I came close to buying the Pickit. However I don't want to be tied down to one manufacturer. I have other projects lined up that may or may not use Atmel chips. Instead of buying a new programmer for each manufacturer, I might as well learn how to do it myself. I also consider it an enriching experience. \$\endgroup\$
    – Daniel
    Nov 10, 2012 at 15:02

Intel HEX files always specify bytes, and addresses in the file are measured in bytes. It is just a convenient format used to transfer binary data between your linker and your programming software. It's up to the programming software that you're using to interpret the data and its addresses and flash it into the PIC correctly.

  • \$\begingroup\$ I understand that the programming software is supposed to interpret the HEX file, however, my current project is to make my own programming software. I am using an Arduino to interface with the MCU. So far I have the Arduino firmware coded, and the GUI shell. All I'm missing now is to interpret the HEX file so I can send the correct information to the Arduino. I am aware of other Arduino->PIC programmer projects, however none of these are compatible with the PIC24. \$\endgroup\$
    – Daniel
    Nov 10, 2012 at 14:07

Although Olin Lathrop has answered the question, I am supplementing his answer with an example of how it would apply to the template I pasted in my original post.

After further investigation of the IDE, I found the memory viewer by accessing Window > PIC Memory Views > Program Memory.

enter image description here

Comparing the table presented in this window with the HEX file, we can notice how the instructions are structured. For the following example, I dividing each address field by two, and spacing out the instructions:

1. :02 0000 04 0000                                fa
2. :08 0000 00 00020400 00000000                   f2
3. :02 0000 04 0000                                fa
4. :10 0004 00 c8020000 ce020000 e4020000 d4020000 92
5. :10 000C 00 da020000 e8020000 ec020000 e0020000 42

Since the data is in big endian form, the bytes appear in reverse order to a hexadecimal literal. Thus changing the data to hexadecimal literals produces the following:

1. :02 0000 04 0000                                        fa
2. :08 0000 00 0x00040200 0x00000000                       f2
3. :02 0000 04 0000                                        fa
4. :10 0004 00 0x000002c8 0x000002ce 0x000002e4 0x000002d4 92
5. :10 000C 00 0x000002da 0x000002e8 0x000002ec 0x000002e0 42
  • \$\begingroup\$ The only change I would make to the converted hex lines, is changing the address to pic24 24 bit addresses. $$\text{1. :02 0000 04 0000} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \text{fa}\\ \text{2. :08 0000 00 0x00040200 0x00000000} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \text{f2}\\ \text{3. :02 0000 04 0000} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\text{fa}\\ \text{4. :10 0002 00 0x000002c8 0x000002ce 0x000002e4 0x000002d4 92}\\ \text{5. :10 0006 00 0x000002da 0x000002e8 0x000002ec 0x000002e0 42}$$ \$\endgroup\$ Sep 26, 2021 at 19:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.