51单片机-关于内存

275 阅读10分钟

51单片机-关于内存

前言

事情是这样子的,今天在用 Keil5 编译代码的时候我发现了一个问题

#include <REGX52.H>
 	
unsigned char LED[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				     0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,};//定义数组

void main()
{
 	while(1){

 	}
}

当我编译以上代码的时候会出现 main.c(28): error C249: 'DATA': SEGMENT TOO LARGE

Data 段太长的错误,这个很好解决,就是STC89C52的RAM比较小存不下,

只要把他存到ROM里面不就可以了!

unsigned char code LED[] //声明数组的时候在这里加个 code就可以了

但是在编译一段定义数组不是很长的代码时候,我又发现一个很奇怪的问题❓

#include <REGX52.H>
 	
unsigned char  LED[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
				      0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,};//定义数组

void main()
{
 	while(1){

 	}
}

编译怎么一段代码的时候,我发现

image-20220328100613811.png

项目大小 data是25字节 code 是164字节

但是在我直接把数组存到ROM中的时候,就是在声明数组的时候多加 code,这时候

image-20220328100856457.png

项目大小 data是9字节 code 是33字节 都变小了?????

我所知道的data 应该指的RAM code 指的应该是ROM

但是我把数组放到ROM 里面为什么RAM 、ROM所占用的空间字节都变小了?????

为此我产生了以下疑问:

  1. 内存ROM、RAM、FLASH之间到底有什么区别?
  2. 51单片机中是怎么存程序怎么存变量的?

为此我查阅了很多资料

ROM、RAM、FALSH

我一开始的理解是 ROM 就相当于电脑的硬盘(掉电仍数据不丢失),RAM 就相当于电脑的内存(掉电丢失,就像剪切板中的内容,关机重启后就没有了)那FLASH就是固态硬盘??

image.png

ROM

ROM(Read Only Memory)只读存储器

顾名思义,它是一种只能读出事先所存的数据的固态半导体存储器。ROM中所存数据稳定,一旦存储数据就再也无法将之改变或者删除,断电后所存数据也不会消失。其结构简单,因而常用于存储各种固化程序和数据。

ROM最初不能编程,出厂什么内容就永远什么内容,不灵活。后来出现了PROM,可以自己写入一次,要是写错了,只能换一片,自认倒霉。人类文明不断进步,终于出现了可多次擦除写入的EPROM,每次擦除要把芯片拿到紫外线上照一下,想一下你往单片机上下了一个程序之后发现有个地方需要加一句话,为此你要把单片机放紫外灯下照半小时,然后才能再下一次,这么折腾一天也改不了几次。历史的车轮不断前进,伟大的EEPROM出现了,拯救了一大批程序员,终于可以随意的修改ROM中的内容了。

EEPROM

EEPROM (Electrically Erasable Programmable read only memory)带电可擦可编程只读存储器

这种ROM的特点是可以随机访问和修改任何一个字节,可以往每个 bit 中写入0或者1。这是最传统的一种EEPROM ,掉电后数据不丢失,可以保存100年,可以擦写100w次。具有较高的可靠性,但是电路复杂/成本也高。因此目前的 EEPROM 都是几十千字节到几百千字节的,绝少有超过512K的。STC89C52拥有5K的EEPEOM。

FLASH(闪存)

FLASH 全称Flash MemoryFlash 属于广义的 EEPROM ,因为它也是电擦除的 ROM 。但是为了区别于一般的按字节为单位的擦写的 EEPROM ,我们都叫它 Flash 。

Flash 做的改进就是擦除时不再以字节为单位,而是以块为单位,以此简化了电路,数据密度更高,降低了成本。所以上M的 ROM 一般都是 Flash 。

Flash分为NOR FlashNAND Flash

NOR Flash数据线和地址线分开,可以实现RAM一样的随机寻址功能,可以读取任何一个字节。但是擦除仍要按块来擦。

NAND Flash同样是按块擦除,但是数据线和地址线复用,不能利用地址线随机寻址。读取只能按页来读取。(NAND Flash按块来擦除,按页来读,NOR Flash没有页)

由于 NAND Flash 引脚上复用,因此读取速度比 NOR Flash 慢一点,但是擦除和写入速度比 NOR Flash 快很多。NAND Flash内部电路更简单,因此数据密度大,体积小,成本也低。因此大容量的Flash都是NAND型的。小容量的2~12M的Flash多是NOR型的。

使用寿命上,NAND Flash的擦除次数是 NOR 的数倍。而且 NAND Flash 可以标记坏块,从而使软件跳过坏块。NOR Flash 一旦损坏便无法再用。

因为 NOR Flash可以进行字节寻址,所以程序可以在NOR Flash中运行。嵌入式系统多用一个小容量的NOR Flash存储引导代码,用一个大容量的NAND Flash存放文件系统和内核。

FLASH 和 EEPROM 的区别

这里我认为最主要的区别是

EEPROM 可以按“位”擦写,而FLASH 只能一大片一大片的擦。

当然还有读入速度、价钱、擦写次数上的区别。

RAM

RAM (Random Access Memory)随机访问存储器

存储单元的内容可按照需要随机取出或存入,且存取的速度与存储单元的位置无关。这种存储器在断电时,将丢失其存储内容,所以主要用于存储短时间使用的程序。速度比ROM、FLASH快。

RAM 分为 SRAM(静态随机存储器)DRAM(动态随机存储器)

SRAM

静态存储单元是在静态触发器的基础上附加门控管而构成的。因此,它是靠触发器的自保功能存储数据的。SRAM存放的信息在不停电的情况下能长时间保留,状态稳定,不需外加刷新电路,从而简化了外部电路设计。但由于SRAM的基本存储电路中所含晶体管较多,故集成度较低,且功耗较大。(寄存器也是一种SRAM)

DRAM

DRAM利用电容存储电荷的原理保存信息,电路简单,集成度高。由于任何电容都存在漏电,因此,当电容存储有电荷时,过一段时间由于电容放电会导致电荷流失,使保存信息丢失。解决的办法是每隔一定时间(一般为2ms)须对DRAM进行读出和再写入,使原处于逻辑电平“l”的电容上所泄放的电荷又得到补充,原处于电平“0”的电容仍保持“0”,这个过程叫DRAM的刷新。

因为 DRAM 需要不断地刷新电路,所以速度上比SRAM 要慢一点。

关于ROM、RAM、FLASH原理

我在B本站上看到了这个up主讲的很好 内存和固态硬盘哪个快?Flash和ROM RAM是一个东西吗?RAM和ROM的区别是什么?_哔哩哔哩_bilibili

51单片机的存储

image-20220328183231897转存失败,建议直接上传图片文件

参考手册我发现 STC89C52 单片机 内置有8K的 Flash 程序存储器 、512字节的 SRAM 和5K 的 EEPROM。

类型功能
Flash在单片机工作的时候只可以读,不可以写,掉电不丢失数据
SRAM可以读,可以写,但是掉电会丢失数据
EEPROM可以读,可以写,掉电不丢失数据

这样就很好理解他们的作用,和最开始的问题了

类型负责
Flash只负责存储程序,如果定义变量的时候加个 code 就是让数据存到Flash中。
SRAM负责存储数据,可以读取,可以改变变量的值,一般我们定义的变量默认要放到RAM里面。
EEPROM负责存储数据,这数据是单片机可以写入的,而却掉电不会丢失。就比如一个时钟,定一个通过按键操作设定6点的闹钟,这时候把数据写入EEPROM就可以将数据存储起来,掉电后数据依然存在。

最开始的问题

为什么我们把在数组前加上code ,让数组存到 Flash 中,但是code反而变小了?

因为 RAM 是掉电丢失数据的, 所以Flash需要存有变量的所有信息,上电后将信息存到 RAM 中,而且还有操作变量存入 RAM 的指令也要存在 Flash 中。

而将变量直接写入 Flash 中,就少了 操作 RAM 的指令的那一部分代码。

这样程序占用 Flash 的空间就反而变少了

几个问题

问题一

如果变量没有赋初值,那么程序占用Flash 和 RAM 的情况是怎么样的呢?

为了解决这个问题我做了以下实验:

image-20220328203319915.png

image-20220328203010353.png

image-20220328203140616.png

image-20220328203140616.png

由此实验我们可知:

  1. 若变量不赋初值,那么data 、code 都暂用 1 个字节。 Flash 开辟 RAM 不需要指令空间
  2. 若变量赋初值, 那么数据占用1个字节,而 Flash 开辟 RAM 空间并赋值 需要2个字节的指令空间

问题二

在变量前 const 和 code 有什么区别?

  1. 是从两个层面是变量不可以更改
  2. 在变量前加 const 是从软件层面声明 常量 ,他一样会存到RAM中,因为声明了是常量所以不可以更改。
  3. 在变量前加 code 是指☞将变量存放在Flash中,而 Flash 是不支持单片机更改数据的。

EEPROM、EPROM、FLASH的区别总结_

EEPROM和flash的区别