Answers:
如今,闪存用于保存程序代码,而EEPROM(电可擦只读存储器)用于保存持久数据。大约30年前,在Flash出现之前,EEPROM被用来保存程序代码。
实际上,首先是ROM(只读存储器),然后是PROM(可编程ROM,仅一次),EPROM(可被紫外线擦除的PROM),EEPROM,最后是闪存。ROM仍用于大量,低成本的应用程序(例如会说话的贺卡)。
与当前微控制器的重要区别在于,通常无法从EEPROM之外执行代码,并且程序将数据存储在闪存中很尴尬。(例如,当您在数据声明中使用“ const”关键字或定义字符串时,数据将存储在闪存中,但由编译器和链接器在后台处理该数据。)
EEPROM区域可用于保存您希望在重新引导期间可用的配置或其他数据,包括微控制器已断电然后重新上电。从功能上讲,您可以将EEPROM视为非常小的硬盘驱动器或SD卡。
在没有EEPROM的微控制器上,可以将持久数据存储在闪存中,但这变得很困难,因为微控制器并不是真正为此设计的,您必须找到一个不会干扰程序代码的特殊位置,并将其放在一边与链接器。另外,如下所述,您通常可以更新EEPROM的次数比刷新次数多。
如果您在Flash中对数据进行编程,这并不意味着您可以在C程序中将数据作为变量进行访问,因为无法告知编译器这些变量在代码中的位置(即,您无法绑定const)因此,必须通过用于写入它们的一组特殊寄存器来读取它们。请注意,此限制也适用于EEPROM中的数据,因此在这方面没有优势。
要对闪存或EEPROM进行编程,必须先擦除一块存储器。然后进行编程。对于闪存,通常一次也要写一个块。对于EEPROM,取决于微控制器,它可以一次以块或一个字节完成。
对于闪存和EEPROM,在耗尽内存之前,最多可以更新它们的次数。数据表中给出此数字作为最低保证值。对于EEPROM,它通常比闪存要高得多。对于闪存,我看到的数字低至1000。对于EEPROM,我看到的数字高达1,000,000。
EEPROM优于闪存的一个优点是,擦除EEPROM的次数比擦除Flash的次数多。
“系统内自编程”仅表示微控制器可以在运行时更新其自己的闪存。该功能通常用于在现场更新代码。诀窍在于,您需要在更新主程序(称为引导加载程序)的同时在系统中保留一些代码。该方案在Arduino系统中用于对芯片进行编程。
我将在@tcrosley的出色回答中添加更多信息。
ATmega16实现了哈佛架构,即系统拓扑,其中数据存储器与程序存储器分开。引用Atmega16数据表(第8页)中的相关段落:
为了最大程度地提高性能和并行性,AVR使用哈佛架构–带有独立的存储器和用于程序和数据的总线。程序存储器中的指令通过单级流水线执行。在执行一条指令时,将从程序存储器中预取下一条指令。这个概念使指令可以在每个时钟周期执行。程序存储器是系统内可重编程闪存。
哈佛架构的优点是,在指令获取周期和数据访问周期之间没有总线争用,因为数据和指令不共享同一条总线,就像在传统的PC架构中一样。
因此,闪存用作程序存储器,而数据存储器则分为SRAM(用于暂存数据,例如函数调用堆栈和堆,例如,如果您使用C编程)和EEPROM(用于永久存储) 。