Search this site (

CCS C Compiler for Microchip PIC micros

Your ad here


PIC16F87x / 16F87xA bootloader

Quick Start

-----Original Message-----
From: Michael
To: Shane Tolmie
Subject: bootloader

Shane - I just gave the latest version (5.10) a shot (along with Petr Kolomaznik's downloader), and it works beautifully. I had been trying to figure out how to get Rick Farmer's PICLOADER to work with my application, but had been coming up blank - your bootloader is absolutely painless, and I don't have to modify my code at all!!

Thanks a lot! - Michael

1. First, connect the serial port of your computer to the PIC micro. The serial port operates at +/- 13V, and the PIC serial operates at +5V/0V. Use a MAX232, MAX3222, or SIPEX232 level shifter to connect the serial port of the computer to pins RX/TX on PIC. For the schematic, see the .gif and Protel 99 .sch files in the distributon download.

You only need one serial port - ignore the M2_xx lines in the schematic as they are not needed for a simple bootloader.

The FAQ at has the same schematic diagrams, plus a troubleshooter guide for non-working serial ports.

2. Select the correct .hex file. You must get the crystal speed correct. Options are 3.6864, 4, 16 and 20Mhz for the 16F873 or 16F876. As far as programming goes, its only based on memory size, so the 2k 16F870/1/2 are the same, the 4k 16F873/4 are the same, and the 8k 16F876/7 are the same. For example, a 16F876, 16Mhz, downloading at 19200 baud would be "61619 - bootldr-v2-16F876-77-16Mhz-19200bps.hex".

3. Recompile your code so it doesnt overwrite the bootloader. This will not normally be necessary, unless your program occupies a lot of memory.

The bootloader uses 256 instructions at the top of flash.

16F876/7, which has 8k of ROM, this is flash locations 0x1F00 to 0x1FFF.
16F873/4, which has 4k of ROM, this is
flash locations 0x0F00 to 0x0FFF.
16F870/1, which has 2k of ROM, this is
flash locations 0x0700 to 0x07FF.

  • Hi-Tech C v8-00 and above, for 8k parts such as the 16F876 or 16F877 add -RESROM1F00-1FFF. This method is recommended over adding the -ICD switch.
  • Hi-Tech C v7.83 or below: add -ICD to the PICC options. This reserves the top 256 bytes of the ROM for the ICD (In-Circuit-Debugger), which means the bootloader also fits in.
  • CCS C: add *only one* of the next two statements, depending on the micro:

    #ORG 0x0700,0x07FF {} //for the 2k 16F870/1/2
    #ORG 0x0F00,0x0FFF {} //for the 4k 16F873/4
    #ORG 0x1F00,0x1FFF {} //for the 8k 16F876/7

    For some versions of CCS C, use the following:
    #org 0x07
    00, 0x07FF void loader16F872(void) {} //for the 2k 16F870/1/2
    #org 0x0F00, 0x0FFF void loader16F874(void) {} //for the 4k 16F873/4
    #org 0x1F00, 0x1FFF void loader16F877(void) {} //for the 8k 16F876/7

  • Assembly: add an equivalent line reserving these program locations.
  • Pascal: its definitely possible. Contact me if you have any problems.

4. This section only applies to bootloader v6-52 and below.

The goto instruction after RESET (address 0x0000-0x0003) is usually a long jump, not a short jump, in 99% of cases. If the bootloader doesnt work, check this out.

The first 4 bytes in the .hex file should be a long jump. (this is true for most .hex files including Hi-Tech C and CCS C). It is known that the CC5X compiler, a Pascal compiler and various assembly language programs do not have this long jump.

If the .hex file has a short jump, ie: goto start, it wont work. The first 4 bytes should have instructions similar to the instructions below:

ORG 0x0000 ;reset vector
clrf 0x3 ;zero status
movlw 0x00 ;high byte of long jump <<<these next 2 lines are important
movwf 0xA ;zero PCLATH
goto start ;ie: if 'start' offset=0xFD, execute long jump to 0x00FD
;bootloader executes these 4 instructions to jump from top of memory, at address 0x1F00, back to program entry point

5. Program the target pic micro with this .hex file with a programmer such as the ICD2 (search for "ICD2" from Third party programmers are discussed at

6. Run "pic_downloader.exe". Choose 19200bps, write eeprom, and the .hex file to download.

To test that the bootloader is working, use the supplied test files. All they do is write serial characters out of the serial port. For example, for a 16Mhz crystal, choose "_19160 - test_serial_19200baud_16Mhz.hex".

7. Click "Write" within the windows application software. It should display the message "Searching for bootloader ..."

8. Reset PIC micro now, and the writing will begin.

9. The test program simply prints out a single text message @ 19200 baud on powerup. Run '' to see the output, this is a HypterTerminal file with settings of 19200,N,8,1,flow control:none.

10. In future, after powerup, bootloader times out in 200ms and then runs the target program normally.

Compatibility list

Note: for the benefit of other users, if you find an addition to this list, please email support@microchipc.comso I can update this list. Your email may save lots of users a lot of time, as it allows me to fix the bootloader. Thanks!

v7-30 has been tested:

  • 16F876 and 16F877, 4Mhz, 10Mhz and 16Mhz for both.
  • Hi-Tech C v7.85, v7.86pl1, pl2, pl3, v7.87.
  • CCS version 2.734, 3.1 See the troubleshooter below.
  • PBPro version 2.31 and 2.32.
  • Assembly language programs that arent too large.
  • Small programs (200 word) and large programs (1 word short of writing over the bootloader).
  • With the MPLab-ICD used as a substitute programmer. The assembly language source must be recompiled.

I am currently working on a version of the bootloader which works with the CC5X compiler - email me if you want a quick fix.

v6-52 of bootloader has been tested with with Hi-Tech C and CCS C compiler, and assembly language programs with a long jump. It does *not* work with PicBasic.

This version of the compiler is known to have issues with the CC5X compiler, and Pascal compiler. These both work if a long jump is inserted into the first 4 bytes (see troubleshooting).



Q. Nothing works - where do I start?

You need a chip programmer to get the bootloader .hex file into the PIC micro in the first place. It is only after the bootloader has been programmed into the PIC micro that new programs can be loaded into the micro using only the RS232 serial port on a PC. The top 4 programmers available are:

Next, check that your circuit is correct. For PIC16F87x, 19200bps, 4Mhz, use "test_serial_19200bps_4Mhz.hex". Program your PIC with the .hex file, and using HyperTerminal set to 19200bps, N,8,1, no hardware flow control, check that it is outputting serial characters. It should repeatedly output a string: [alive].

  • The bootloader has been changed to work with the 16F87xA.
  • A MAX232 needs at least 1.0uF capacitors, different from the MAX232A which only needs 0.1uF capacitors.
  • A MAX233 doesnt need any capacitors.
  • The bootloader does not work with the 16F872 as it doesnt have a UART.
  • Check that your compiler is compatible.
Next (3 steps remaining) >>


Q. I want to use the MPLab-ICD with the bootloader

Yes, this works nicely.

However, first you must re-assemble the included .asm file.

The MPLab-ICD uses the top 256 bytes of memory on the 16F876 for its own purposes.

Normally, the bootloader uses the top 256 instructions in memory. So, move the bootloader down 256 instructions to sit below the MPLab-ICD reserved memory, by re-assembling it.

In the supplied .zip file, in the directory 'assembly source', open up bootldr.asm. Change the #define ICD_DEBUG 0 to #define ICD_DEBUG 1. Check crystal speed, and re-assemble.

After this, you must reserve the top 512 instructions in your application for the bootloader/MPLab-ICD combination.

For example, for Hi-Tech C v8-00 and above, with 8k parts such as the 16F876 or 16F877, add the command line option -ICD for the ICD. This reserves the top 256 instructions, and some ram (0x70 and more) for the ICD. In addition, add -RESROM1E00-1EFF to reserve 256 instructions below the ICD memory for the bootloader. Do not combine these two command line calls into -RESROM1E00-1FFF as this doesnt reserve the ram needed for the ICD.

Now, remember to have enable debug mode set to 'off', see the screenshot here. Program the bootloader .hex file into the 16F876 with the MPLab-ICD, then try it out.

Next (2 step remaining) >>

Q. I got the bootloader detecting and downloading with the supplied serial comms circuit, but my program doesnt work with it.

Your program will work, dont give up! However, the most common problems are, in order of rarity:
  • Your program should *not* use the top 256 bytes of program memory. See reserving memory.
  • Your compiler / assembler may not be compatible. See compatible compiler.
  • New in v7.60, the bootloader works with both low voltage and normal 5V chips.
Next (1 step remaining) >>

Q. Is your compiler compatible with the bootloader?

Hi-Tech C is compatible. Reserve top 256 of memory locations for bootloader. Heres how.

CCS C is compatible. For, simply reserve top 256 of memory locations for bootloader. Heres how.

language is compatible, with possible modifications.
Check conditions.

PicBasic is compatible, with modifications. Heres how.

CC5X compiler is compatible, with modifications. Heres how.

All others compiler / assemblers. Check conditions for correct operation.

Q. Can I run the bootloader with WDT enabled?

Yes. For modifications, see instructions in the distribution download.

Q Why does my circuit keep resetting? Or not start up at all?

By default, if you have Low Voltage Programming (LVP) enabled, touching pin RB4 will reset the micro. In the worst case, a bad logic level on RB4 will keep the micro in reset.

Troubleshooter is Finished

Answers to Troubleshooting Questions


Q. Have you reserved space for bootloader?

The bootloader needs the top 256 bytes of memory for itself. Add instructions to reserve these memory locations.

  • For a 4k 16F873 or 16F874, this is memory locations 0xF00 to 0xFFF.
  • For an 8k 16F876 or 16F877, this is memory locations 0x1F00 to 0x1FFF.

For the Hi-Tech C compiler, the -ICD compiler switch reserves the top 256 instructions for the In-Circuit Debugger. Add this switch to the compiler options in project setup to reserve space for the bootloader.

For CCS C, add one of the following lines:

#org 0x0700, 0x07FF void loader16F872(void) {} //protect bootloader code for the 2k 16F870/1/2
#org 0x0F00, 0x0FFF void loader16F873(void) {} //
protect bootloader code for the 4k 16F873/4
#org 0x1F00, 0x1FFF void loader16F876(void) {} //
protect bootloader code for the 8k 16F876/7

For PicBasic:
yet to be advised - email me if you know!

The CC5X needs a modification to the source code. See the complete solution.

For Assembly language: add an equivalent line reserving these program locations.


A. How to make the CC5X compiler work with the bootloader

If you have CC5X v2.74, then perform step 1 only - the bootloader just needs the top 256 bytes of memory reserved for the bootloader.

If you have CC5X v3.1, then perform steps 1 and 2 - the reset jump must also be altered to clear PCLATH on startup.

These statements have to be entered in the beginning of the C program:

  1. Reserve the top 256 instructions for the bootloader. These statements can be placed in user program, but should replace the original statements in the header files for these processors, 16F877.h and 16F873.h.

    For a PIC16F876 or PIC16F877 with 8k of FLASH:

    #pragma chip PIC16F873, core 14, code 0x1F00, ram 32 : 0xFF /0 /3 //set top address to protect bootloader code

    For a PIC16F873 or PIC16F874 with 4k of FLASH:
    #pragma chip PIC16F873, core 14, code 0x0F00, ram 32 : 0xFF //set top address to protect bootloader code

  2. Manually set the PCLATH register and add a few NOP instructions.

    #pragma cdata[0] = 0x0180 + 0x0A // CLRF PCLATH, prepare for code page change
    #pragma cdata[1] = 0 // NOP
    #pragma cdata[2] = 0 // NOP
    #pragma resetVector 3 // start address for user program

This setting also works with interrupt function which will be placed with starting address 0x04.

CC5x v3.1 have these commands, this is not tested with older versions of CC5x.

Download demonstration CC5x v3.1 project.

- Many grateful thanks to Tore Bergvill from Oslo, Norway and Pierre Brochard, Paris.


Q. What conditions are necessary for a generic assembler / compiler to work with the bootloader?

Check that the top 256 instructions of flash are reserved. Heres how.

If your compiler / assembler is on the compatibility list, modify it as per instructions. Heres how.

If this fails, the first 4 bytes in the .hex file should be a long jump. This is fairly standard - most compilers have this by default.

However, for some assembler programs or Pascal compilers, there may be a short jump, without a PCLATH=0 instruction. This won't work in some circumstances (eg: the CC5X compiler needs changes - see here). If you're programming in assembler, match the first 4 lines of your program to that below.

Heres an example of the first 4 instructions that the Hi-Tech C compiler uses. This works perfectly.

ORG 0x0000 ;reset vector
clrf 0x3 ;zero status
movlw 0x00 ;high byte of long jump
movwf 0xA ;zero PCLATH
goto start ;ie: if 'start' offset=0xFD, execute long jump to 0x00FD
;bootloader executes these 4 instructions to jump from top of memory, back to program entry point
;reset vector is at ORG 0x0004, from here on.



Q. What about PICBasic?

The latest version of the bootloader works perfectly
with PicBasic.

  • PicBasic v2.33 - First line in the program should be DEFINE LOADER_USED 1. This command tells the compiler to start at location 0x004.
  • PicBasic v2.31 and 2.32 - First line in the program should be DEFINE ONINT_USED 1

Note: If PBpro interrupts are used, there is no need for either of these defines.


Q. Can I run the bootloader with WDT enabled?

Yes. Here is an email I received from a user ...

"Hello Shane,

I was download your PIC bootloader archive v8.01 and try it with
some of my HiTech PICC code. In my code watchdog must be enabled and
when I download it to PIC it does not work even if I enable WDT when
programming PIC. So, I look in your asm code of bootloader and found
this piece of code:

btfss STATUS,NOT_TO ;run user program after WatchDog-TimeOut
goto UserStart
movlw 0x90

In PIC16F87x datasheet I found this table:

0 x 1 1 Power-on Reset
0 x 0 x Illegal, TO is set on POR
0 x x 0 Illegal, PD is set on POR
1 0 1 1 Brown-out Reset
1 1 0 1 WDT Reset
1 1 0 0 WDT Wake-up
1 1 u u MCLR Reset during normal operation
1 1 1 0 MCLR Reset during SLEEP or interrupt wake-up from SLEEP

so I notice that the above code must be changed for proper operation
with WDT enabled:

btfsc STATUS,NOT_TO ; run user program after WatchDog-TimeOut
goto start
goto UserStart
movlw 0x90

Now, with this code I can test programs with or with out WDT enabled
and used.

I hope you understand my English and what I want to say.

[Thanks for this info! - Ed.]

ICQ: 15616778

This site is non-profit. Ad revenue almost covers hosting costs.

We welcome any suggesions or comments! Send them to Shane Tolmie on This site is a completely separate site to, and is maintained independently of Microchip Ltd., manufacturers of the PIC micro. All code on this site is free for non-commercial use, unless stated otherwise. Commercial use normally free, however, it is prohibited without contacting for permission. All content on this site created by Shane Tolmie is copyrighted by Shane Tolmie 1999-2009. Click to advertise on this website - $29.90 for a banner ad which will reach 55,000 user sessions per month. One months free trial!