Hoy en día, la memoria Flash se usa para guardar el código del programa, y la EEPROM (memoria de solo lectura borrable eléctricamente) se usa para guardar datos persistentes. Hace unos 30 años, antes de que apareciera Flash, las EEPROM se usaban para contener el código del programa.
En realidad, ROM (memoria de solo lectura) vino primero, luego PROM (ROM programable, solo una vez), EPROM (PROM borrable con luz UV), EEPROM y finalmente Flash. Las ROM todavía se usan para aplicaciones de muy alto volumen y bajo costo (por ejemplo, tarjetas de felicitación parlantes).
La diferencia importante con los microcontroladores actuales es que generalmente no se puede ejecutar código desde EEPROM, y es incómodo que los programas almacenen datos en flash. (Los datos se almacenan en flash cuando, por ejemplo, utiliza la palabra clave "const" en una declaración de datos, o define una cadena, pero el compilador y el vinculador se encargan de ocultarlos).
El área EEPROM se puede usar para mantener la configuración u otros datos que desea que estén disponibles en los reinicios, incluso si el microcontrolador ha perdido energía y luego se vuelve a encender. Funcionalmente, puede pensar en la EEPROM como un disco duro muy pequeño o una tarjeta SD.
En los microcontroladores sin EEPROM, es posible almacenar datos persistentes en la memoria flash, pero esto se vuelve difícil ya que los microcontroladores realmente no fueron diseñados para esto, y debe encontrar un lugar especial que no interfiera con el código del programa, y dejar esto a un lado con el enlazador Además, como se menciona a continuación, generalmente puede actualizar la EEPROM muchas veces más que el flash.
Si programa los datos en flash, esto no significa que puede acceder a los datos como variables en su programa C, porque no hay forma de decirle al compilador dónde están estas variables en su código (es decir, no puede vincular una constante variable a esta área de flash.) Entonces, leerlos debe hacerse a través del conjunto especial de registros que se utilizan para escribirlos. Tenga en cuenta que esta restricción se aplica a los datos en EEPROM también, por lo que no tiene ninguna ventaja a este respecto.
Para programar flash o EEPROM, primero se debe borrar un bloque de memoria. Entonces se programa. Para flash, la escritura generalmente también se realiza un bloque a la vez. Para EEPROM, se puede hacer por bloques o un byte a la vez, dependiendo del microcontrolador.
Tanto para flash como para EEPROM, hay un número máximo de veces que puede actualizarlas antes de agotar la memoria. Este número se proporciona en la hoja de datos como un valor mínimo garantizado. Por lo general, es mucho más alto para EEPROM que para memoria flash. Para flash, he visto números tan bajos como 1000. Para EEPROM, he visto números tan altos como 1,000,000.
Una ventaja de las EEPROM sobre el flash es que puede borrarlas muchas veces más de lo que puede borrar el flash.
"Autoprogramable en el sistema" simplemente significa que el microcontrolador puede actualizar su propio flash mientras se ejecuta. La característica generalmente se usa para actualizar el código en el campo. El truco es que debe dejar algo de código en el sistema mientras se actualiza el programa principal, llamado cargador de arranque. Este esquema se utiliza en el sistema Arduino para programar el chip.
Agregaré más información a la excelente respuesta de @tcrosley.
El ATmega16 implementa una arquitectura de Harvard , es decir, una topología del sistema donde la memoria de datos se separa de la memoria del programa. Citando el párrafo relevante de la hoja de datos de Atmega16 (página 8):
La arquitectura de Harvard tiene la ventaja de no tener contención de bus entre los ciclos de obtención de instrucciones y los ciclos de acceso a datos, ya que los datos y las instrucciones no comparten el mismo bus, como en la arquitectura de PC convencional.
Por lo tanto, la memoria flash se usa como memoria de programa, mientras que la memoria de datos se divide entre SRAM (para datos transitorios, como la pila de llamadas de función y el montón, si está programando en C, por ejemplo) y la EEPROM (para almacenamiento permanente) .
fuente