Flash and EEPROM

Nowadays, Flash memory is used to hold program code, and EEPROM (Electrically Erasable Read-only Memory) is used to hold persistent data. Back some 30 years ago, before Flash came along, EEPROMs were used to hold program code.

Actually ROM (Read-Only Memory) came first, then PROM (Programmable ROM, once only), EPROM (PROM Erasable with UV light), EEPROM, and finally Flash. ROMs are still used for very high-volume, low-cost applications (e.g. talking greeting cards).

The important difference with current microcontrollers is that you cannot generally execute code out of EEPROM, and it is awkward for programs to store data in flash. (Data is stored in flash when for example you use the "const" keyword in a data declaration, or define a string, but that is handled behind the scenes by the compiler and linker.)

The EEPROM area can be used to hold configuration or other data which you want to be available across reboots including if the microcontroller has lost power and is then powered back up. Functionally, you can think of the EEPROM as a very small hard drive or SD card.

On microcontrollers without EEPROM, it is possible to store persistent data in flash memory, but this becomes difficult since microcontrollers were not really designed for this, and you have to find a special spot that will not interfere with the program code, and set this aside with the linker. Plus as mentioned below, you can usually update the EEPROM many times more than the flash.

If you do program data in flash, this doesn't mean you can access the data as variables in your C program, because there is no way to tell the compiler where these variables are in your code (i.e. you can't bind a const variable to this area of flash.) So reading them has to be done through the special set of registers that are used to write them. Note this restriction applies to the data in EEPROM also, so it has no advantage in this regard.

To program either flash or EEPROM, a block of memory first must be erased. Then it is programmed. For flash, writing is usually done a block at a time also. For EEPROMs, it can be done by blocks or a byte at a time, depending on the microcontroller.

For both flash and EEPROMs, there is a maximum number of times you can update them before you wear out the memory. This number is given in the datasheet as a minimum guaranteed value. It is usually much higher for EEPROMs than for flash memory. For flash, I have seen numbers as low as 1000. For EEPROMs, I have seen numbers as high as 1,000,000.

One advantage of EEPROMs over flash, is that you can erase them many more times than you can erase flash.

"In-System Self-programmable" simply means the microcontroller can update its own flash while running. The feature is usually used to updated code in the field. The trick is that you need to leave some code in the system while the main program is being updated, called the bootloader. This scheme is used in the Arduino system to program the chip.


I'll add some more info to the excellent answer by @tcrosley.

The ATmega16 implements an Harvard architecture, i.e. a system topology where the data memory is separated from the program memory. Quoting the relevant paragraph from the Atmega16 datasheet (page 8):

In order to maximize performance and parallelism, the AVR uses a Harvard architecture – with separate memories and buses for program and data. Instructions in the program memory are executed with a single level pipelining. While one instruction is being executed, the next instruc- tion is pre-fetched from the program memory. This concept enables instructions to be executed in every clock cycle. The program memory is In-System Reprogrammable Flash memory.

Harvard architecture has the advantage of having no bus contention between instruction fetching cycles and data access cycles, since data and instructions don't share the same bus, like in your conventional PC architecture.

Therefore the flash memory is used as the program memory, whereas the data memory is split between SRAM (for transient data, like function call stack and the heap - if you are programming in C, for example) and the EEPROM (for permanent storage).