PIC Hex File Format

Microchip have scored a winner over Atmel AVR by including all the information required to program a PIC microcontroller in one Hex file. This includes code, EEPROM data, User bytes (User ID) and most importantly, configuration words.

This makes it much easier to transfer the project from development to production or between engineers, as all the information needed is in one file. No equivalent mechanism exists for the AVR and describing fuse settings for AVR is always a headache. Kanda
AVR Programmers have to include a project mechanism to achieve the same result. So, what is this file format?


You need to add configuration byte data to your source file in C or assembler. The syntax does vary for different tools and C or assembler. PIC16F examples in Microchip C or assembler use __Config directive, for example,
__CONFIG(0x3F72);

Another, in assembler, is
__config _CP_OFF & _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF & _BODEN_ON

PIC18F usually use CONFIG directive, for example,
CONFIG WDT=OFF; disable watchdog timer
CONFIG MCLRE = ON; MCLEAR Pin on
CONFIG DEBUG = ON; Enable Debug Mode
CONFIG LVP = OFF;

Check your compiler documentation for more details. Configuration bit names vary from PIC device to PIC device, see “Special Features of CPU section” in PIC device datasheets for details about configuration bytes.

MPLAB X
The latest MPLAB X deals with Configuration Bytes differently in C files. With MPLAB X assembler files, __CONFIG and CONFIG directives still work but the C compiler requires a different format. It requires the use of #pragma config WDTE = ON syntax.

The easiest way to generate the required #pragma directives is with a built-in Configuration Bytes Tool.

Go to Window menu -> PIC Memory View -> Configuration bytes.
A window opens with a list of the possible configuration bytes available on device that is set in the project. The available Configuration bytes are different for PIC18F chips but the method is the same. Set them how you want and click “Generate Source Code to Output button. This creates the code you need to cut and paste into your main source file, or put in a separate C file and use #include directive in your main file.

Example PIC18F Configuration Bytes in MPLAB X
#include <xc.h>

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG1H
#pragma config OSC = RCIO // Oscillator (External RC oscillator, port function on RA6)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

Example PIC16F Configuration Bytes in MPLAB X
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG1
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = ON // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = ON // Internal External Switchover bit (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#pragma config LVP = OFF

These directives will add the Configuration bytes to the output Hex file, which is described next.

HEX FILE FORMAT FOR PIC18F DEVICES

A Microchip format Hex file is an extended Intel Hex file with code, data, configuration bytes and user ID included. You need to select output file type as INHX32. This is 32-bit addressing as Configuration bytes are stored above 64KB, which is the limit for 8-bit Intel Hex format, INHX8. All PIC programmers should be able to cope with this format, and PIC compilers should produce it.

Each line in the file has this format:

:BBAAAATT[DDDDDDDD]CC

where
: is start of line marker
BB is number of data bytes on line
AAAA is address in bytes
TT is type. 00 means data, 01 means EOF, 02 means linear address and 04 means extended address
DD is data bytes, number depends on BB value
CC is checksum (2s-complement of number of bytes+address+data)

Extended and Linear Addressing
Standard Intel Hex files can only address 64KB of data (0..FFFFh), and extended addressing gets over this limitation by adding extended address lines for every 64KB, for example

:020000040001F9 – 64KB marker
:020000040002F9 – 128KB marker

The Extended Address – 04 – marker means shift the value given after 04 16 places left.
The line :020000040001F9 means shift 1 16 places left, which gives 10000h, which in decimal is 65536 or 64KB. Shifting 2 16 places left gives 20000h or 128KB and so on.
The address of all data after the marker has the marker value added to it.

The next complication is that some compilers use Linear Address instead of Extended
Address. This works in a similar way but the marker is 02 not 04 and the value is only shifted left 4 places. The equivalent 64KB marker in linear addressing format is

:020000021000EC – 64KB marker

Shifting the value after the 02 marker, which is 1000, four places left also gives 10000 or 64KB. Note that the checksum will change. You may see either format used in PIC Hex files.

Some compilers include empty code lines (all FF) but others omit these lines to save space.

Code: This is at the top of the file and may be proceeded by an extended address line – :020000040000FA, where 04 is the type for extended address or by a linear address, 02. In both cases, the resulting address value is still 0x0000 so it actually has no effect.

EEPROM Data: It is proceeded by the extended address line – :0200000400F00A. The EEPROM section is optional

Configuration bytes: These are stored at 300000h and are preceded by the extended address line – :020000040030CA. The correct format is 8 Fuse bytes and 6 Lock bytes all on the same line but different compilers and assemblers have different methods of displaying these bytes. Sometimes lock bytes are omitted if they are not set, sometimes the data is spread over multiple lines.
The standard format displays unused bits as 1 (e.g. FF for an unused byte) but on the PIC device they read as 0. A programmer should mask unused bits to 0 so that the Configuration Byte will verify correctly.

User ID: These are bytes for the user to store data, such as code version numbers. They are stored at 200000h. Again they are preceded by the extended address line :020000040020DA. The standard format requires 8 bytes but again some compilers omit unused bytes.

End of File: The End Of File marker for all Intel Hex files is :00000001FF

Example

:100000003C932014BBE0AD7A3EAC4D261FB267A4F2
:100010008121F4C2D641A503B6038C9932A36EBCEC
:10002000D204306AE84404FCE8C7452DE0BE3160E4
:100030005CC6E94D3F4E62765AC237EAD3C2895157
:0200000400F00A
:10000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
:020000040030CA
:1000000000270F0F0083F500FFC0FFE0FF400000C5
:020000040020DA
:080000000102030405060708D4
:00000001FF

This shows 4 lines of code, 1 line of EEPROM data at :0200000400F00A, 8 user User bytes at :020000040020CA and 16 Configuration bytes at :020000040030CA, the last 2 are dummies as it only has 14 configation bytes.

HEX FILE FORMAT FOR PIC16F DEVICES

The PIC16F file has a similar format to the PIC18F file but does not use extended addressing as the PIC16F devices are smaller. This section is not correct for the latest PIC16F1xxx chips – see separate section below.

Code: Code is always at the top of the .hex file. The layout varies with different compilers and assemblers e.g. amount of data per line, whether blank lines are included etc. Note that the PIC16F devices use 14-bit instructions, so code is stored as Words with low byte first. Therefore, an unused location appears as FF3F. Addressing is in bytes though.

EEPROM Data: If the device has EEPROM, the data is stored at address 0x4200 upwards in the HEX file. It is stored in word format but only the lower byte contains data – the high byte is always 0 and is discarded.

Configuration Word: There is only one 14-bit configuration word on most PIC16F, stored at address 0x400E. It is stored high byte first. Some devices have up to 3 words.

User Data: Up to 8 bytes stored at 0x4000.

End of File: The End Of File marker for all Intel Hex files is :00000001FF

Example

:100000005D38A23BB437B11731090A0F1202E92358
:100010007B3E20286F335609A104A12BB00DE92D9A
:100020008D22260D260A931C951D510C6711131065
:10420000FF00FF00FF00FF00FF00FF00FF00FF00B6
:06400E00FF3FFF3FFF3FF2
:08400000FF3FFF3FFF3FFF3FC0
:00000001FF

HEX FILE FORMAT FOR PIC16F1xxx DEVICES

Earlier PIC16F microcontrollers had less than 16KB of code memory. The EEPROM data, User ID and configuration bytes were also stored below 64KB, so standard Intel Hex files were fine.

The newer PIC16F1xxx devices are bigger, with the latest having 64KB of program space. To accommodate this larger flash memory, the other data in the hex file was moved above 64KB and Extended or Linear addressing is required to access this – see PIC18F section for a full description of these addressing modes.

Code
This is still stored from address 0x0000 but may have an extended or linear address line at the start eg :020000040000FA. This still means start the code at 0x0000. As the maximum code size is 64KB, the file doesn’t actually need extended addressing to accommodate the code.

EEPROM
EEPROM data is stored starting at address 0x1E000. This means it must have an extended address marker before it, :020000040001FA or :020000021000EC. This gives a base address of 0x10000 and the EEPROM data address, starting at E000 is added to this.
:10E00000FF00FF00FF00FF00FF00FF00FF00FF0018
Note that the 8-bit EEPROM data is padded with 00, which is discarded when the PIC device is programmed.

User ID
There are 4 14-bit words of User ID, stored at address 0x10000 to 0x10003. They are usually stored on one line but can appear spread over different lines.

Configuration Bytes
The number of configuration bytes varies from 2 to 5 and they are actually 14-bit words. They start at address 0x1000E and may appear on one line or each may have its own line.

Example

:020000040000FA Extended Address 0x0000
:020000000428D2 Code
:040002000034003492
:080008004001003094004001AA
:10001000FF308E0000308E001120FF308E00112046
:100020000A280130A0000130A1000A30A200A00B74
:0C0030001728A10B1728A20B17280800A6 End of Code
:020000040001F9 Extended Address 0x10000
:10E0000061006200630064006500660067006800EC EEPROM
:10E01000FF00FF00FF00FF00FF00FF00FF00FF0008 EEPROM
:080000000100020003000400EE User ID 0x10000
:02000E00DA1FF7 Configuration starting at 0x1000E
:020010003F2986
:020012009F0746
:02001400FC3EB0
:02001600FF3FAA Last configuration
:00000001FF End of File

Although EEPROM is stored at a higher address (0x1E000) it usually appears in the hex file before User ID, stored at 0x10000, and Configuration, stored at 0x1000E. Program code can also be stored out of normal address order by some tools.

Related Information

Choosing the Right PIC Microcontroller

PIC ICSP Methods

PIC ICSP Circuit Schematic

MPLAB X Explored

9 thoughts on “PIC Hex File Format”

  1. The configuration bytes for PIC18F in the example are these

    :020000040030CA
    :1000000000270F0F0083F500FFC0FFE0FF400000C5

    From the hex file description, if we omit the hex file formatting we get 16 data bytes like this
    00270F0F0083F500FFC0FFE0FF400000

    These are the configuration bytes from Config1L to Config7H (14 bytes). The last 2 bytes are dummies. The bottom 8 are configuration, and next 6 are lock bytes. If you look in a PIC datasheet under “Special Features of the CPU” section, you will see all the configuration bits laid out and described.

  2. Admiring the time and effort you put into your blog and in depth information you provide. It’s awesome to come across a blog every once in a while that isn’t the same unwanted rehashed material. Great read! I’ve saved your site and I’m including your RSS feeds to my Google account.

  3. Hello there, I believe your site could possibly be having web
    browser compatibility problems. Whenever I take a look at your website in Safari, it looks fine but when opening in
    Internet Explorer, it has some overlapping issues.

    I just wanted to provide you with a quick heads
    up! Besides that, excellent site!

    1. Hi
      Thanks for the feedback. It is ok here in IE 8 +, perhaps you have an old browser version or a strange screen resolution.

  4. So If I have A compiled Pic Hex code it will have The configuration bits Already set so I don’t nee to set them when burning the Chip?

    Mike

    1. As long as you add the configuration bits to your MPLAB project, they will be in the hex file. All PIC programmers (I think all, certainly all the ones we sell) will program the configuration bits from the hex file and will moan if they aren’t there.

      To add congiguration bytes to your MPLAB project, use __CONFIG or CONFIG directives in MPLAB 8, or #pragma config in MPLAB X – there is a tool to do this in MPLAB X under Windows menu -> PIC Memory Views -> Configuration Bits.

      Please see another blog post on MPLAB X for more information MPLAB 8 versus MPLAB X

  5. What’s Going down i am new to this, I stumbled upon this I have found It absolutely helpful and it has aided me out loads.
    I am hoping to contribute & assist different users like its helped me.
    Great job.

Leave a Reply

Your email address will not be published. Required fields are marked *