Many microcontrollers, e.g. PIC18F, have flash program memory: "The Flash program memory is readable and writable during normal operation". Does this mean I can store some user configurations in the program memory?


2 Answers 2


Yes, you can. I have done this many times.

However, there are some drawbacks relative to using separate EEPROM:

  1. The number of lifetime writes to program flash memory is significantly less than data EEPROM.

  2. The processor will go out to lunch during the erase and write times.

  3. Program flash is erased in blocks. You can't just update a single byte. I usually use a block caching scheme to deal with this.

  • \$\begingroup\$ Perfect, you seem to somehow know that my question is really "why the need for EEPROM while you can use the program memory for both program and user data" :) \$\endgroup\$
    – student1
    Dec 10, 2014 at 19:58
  • \$\begingroup\$ Olin, does all of the Flash get erased when new version of firmware is burned into the PIC? Is there a good way to prevent the user configuration (or calibration data) in the Flash from being erased during firmware download? This is about convenience during firmware development. I would imagine that the user configuration would be stored in the very last block or Flash. \$\endgroup\$ Dec 10, 2014 at 20:02
  • 6
    \$\begingroup\$ @Nick: That is up to the PIC programmer you are using. Many, including all of mine, do a bulk erase, so calibration data would get wiped out. I have on a few occasions written a special programming app that read the calibration data, did the bulk erase, then wrote the calibration data back out as part of the normal programming process. Some of the Microchip programmers may be able to update only parts of the program memory. Note that if you turned on code protection, the programmer must do a bulk erase. \$\endgroup\$ Dec 10, 2014 at 20:05
  • \$\begingroup\$ On non-Harvard processors (I'm thinking of MSP430) you can copy code into RAM, and jump into RAM and run while flash write/erase takes place. I've used this for a bootloader, to simultaneously write and receive new data from a radio. \$\endgroup\$
    – markrages
    Dec 11, 2014 at 1:48
  • \$\begingroup\$ @mark: Yes, this also works on PIC32, where it is also possible to execute from RAM. In fact, that's faster. \$\endgroup\$ Dec 11, 2014 at 14:27

Many PIC18's have EEPROM memory, up to 1K in size. Unfortunately the PIC18F46J50 you reference does not. If EEPROM is available, it is a much better choice if it is large enough for your data, as the EEPROM has a minimum of 1,000,000 erase/write cycles, and the flash is only 10,000.

The PIC18, like most other microcontrollers, uses what is called a Harvard architecture, meaning there are physically separate addressable area for programs and data (i.e. you can have a program address 4 and a data address 4, and they are not the same). Therefore you cannot read or write flash memory using the normal methods in either C or assembly language.

Instead, on the PIC18 family, you set up a starting address in a 22-bit register called TBLPTR. To read bytes from the flash, you use a TBLRD instruction. There is an option to automatically increment or decrement the address after a read you don't have to do that manually.

To write to flash memory, you have to erase one or more 64-byte blocks of flash memory first that will be written over. After setting up the starting address again in TBLPTR, and values in some other registers to initialize the erase operation, interrupts are disabled and then you must write 0x55 immediately followed by 0xAA to a register; this unlocks the erase command and is needed to prevent errant code from accidentally wiping out memory. Finally the command to actually do the erase is executed, followed by re-enabling interrupts.

Writing to flash memory is similar to erasing, except the block size is smaller. The write is actually executed using a TBLWT instruction, which also allows auto increment/decrement like the TBLRD instruction.

In addition to saving off configuration data, writing to flash memory allows one to update their firmware in the field using what is called "firmware over the air". You need to have a fixed block of firmware, usually at the start of program memory, that can receive the update from a Bluetooth module, Wi-Fi, cellular module, or even a wired connection, and update the flash above a certain point in the program (e.g. a "fence") with new code. After the update is completed, a reset is initiated, and the new code is put into use.

Many other microcontrollers besides the PIC family have the ability to update their flash memory; most use some combination of configuration registers, an address pointer, and special instructions to carry out the task.

  • \$\begingroup\$ That "firmware over the air" method looks very interesting. Does it remove the need for In System Programming (ISP)? \$\endgroup\$
    – student1
    Dec 11, 2014 at 1:01
  • \$\begingroup\$ @student1 It doesn't remove the need for initial programming of the chip via an ISP interface, because you have to put some firmware on the chip to be able to handle the updates later on. The ATmega microcontrollers used on the Arduino boards already have this type of firmware on them, called the Bootloader, which is why you don't need to use an ISP interface to download sketches to an Arduino. However if you want to update the Bootloader itself, that does requires an ISP interface. This Bootloader only handles updates over USB, so it is not really "firmware over the air". \$\endgroup\$
    – tcrosley
    Dec 11, 2014 at 8:30

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.