STM32芯片的ROM与RAM
STM32片内FLASH特定地址写入数据不被擦除方法

STM32中存储区分为:随机存取存储器RAM和只读存储器ROM。
其中:RAM为常说的存,比如手机的2G存4G存等,就是程序跑起来的时候所占用的存储空间,特点是掉电数据丢失。
ROM为常说的硬盘,比如手机的64G和128G等,可以简单的理解为硬盘的存储空间,特点是掉电数据不丢失,所以又叫“非易失性存储器件”。
ROM又包含:EEPROM和flash。
作为ROM的一份子,flash的特点自然是掉电数据不丢失。
但是,flash在STM32中比较重要,程序也是保存在这个地方,所以轻易不让用户进行随意的读写,以避免不必要的问题。
1、STM32 FLASH操作流程Flash操作已经属于嵌入式设备中很底层的操作了,直接对地址进行存取,简单描述,Flash操作大致需要以下流程:1、确定要写入Flash的首地址(稍后介绍确定地址的方法)2、解锁Flash3、对Flash进行操作(写入数据)4、对Flash重新上锁1.1 如何查找并选定要写入Flash十六进制地址值的方法要想选定安全的Flash地址进行读写,可以根据自己的STM32 MCU型号,查找数据手册,确定FLASH的地址区段,因为起始段会存储代码,所以一定要避开起始段,以避免数据错误。
(我一般是根据Flash大小计算Flash的最末尾地址,往前推一段地址空间,在这里一般不会对代码中的数据产生覆盖等影响)我此次操作Flash使用的MCU是STM32103C8T6,所以以该型号MCU为例进行描述:在数据手册中,可以看到STM32103C8T6的flash起始地址是0x0800 0000(如下图所示),而STM32103C8T6的Flash大小为64K,可以计算出STM32103C8T6的Flash地址围是:0x0800 0000——0x0800 FFFF(计算方法参考另一篇博客:STM32存大小与地址的对应关系以及计算方法)。
这里选取0x0800 F000作为读写操作的起始地址,对于C8T6这款MCU,操作这个起始地址应该算是很安全的围了。
ram和rom的工作原理

ram和rom的工作原理
RAM(Random Access Memory)随机存取存储器和ROM(Read-Only Memory)只读存储器是计算机中用于存储数据和程序的两种不同类型的内存。
RAM 的工作原理是基于电容器的充电和放电。
RAM 芯片由许多微小的电容器组成,每个电容器可以存储一个二进制位(0 或1)。
当需要存储数据时,电容器会被充电以表示1,而放电则表示0。
RAM 可以快速地读取和写入数据,因为它可以直接访问任何存储单元,而无需按顺序访问。
ROM 的工作原理则是基于晶体管的开关状态。
ROM 芯片中的晶体管被编程为特定的状态,以表示二进制数据。
ROM 中的数据是在制造过程中被写入的,并且通常不能被修改。
ROM 通常用于存储计算机的基本输入输出系统(BIOS)、操作系统的启动代码以及其他固定的程序和数据。
在计算机中,RAM 和ROM 通常协同工作。
RAM 用于存储正在运行的程序和数据,因为它可以快速地读写。
而ROM 则用于存储固定的程序和数据,如BIOS 和操作系统的启动代码,因为它的读取速度较快且具有持久性。
RAM 和ROM 的工作原理都是基于电子元件的状态来存储数据。
RAM 是易失性存储器,可快速读写,但数据在断电后会丢失。
ROM 是非易失性存储器,数据在断电后仍然保留,但通常只能读取而不能写入。
STM32 的三种不同启动模式

STM32 的三种不同启动模式STM32 三种启动模式对应的存储介质均是芯片内置的,它们是:1. 用户闪存:芯片内置的Flash。
2. SRAM:芯片内置的RAM 区,就是内存啦。
3. 系统存储器:芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段Bootloader,就是通常说的ISP 程序。
这个区域的内容在芯片出厂后没有人能够修改或擦除,即它是一个ROM 区。
在每个STM32 的芯片上都有两个管脚BOOT0 和BOOT1,这两个管脚在芯片复位时的电平状态决定了芯片复位后从哪个区域开始执行程序,见下表:BOOT1=x BOOT0=0 从用户闪存启动,这是正常的工作模式。
BOOT1=0 BOOT0=1 从系统存储器启动,这种模式启动的程序功能由厂家设置。
BOOT1=1 BOOT0=1 从内置SRAM 启动,这种模式可以用于调试。
要注意的是,一般不使用内置SRAM 启动(BOOT1=1 BOOT0=1),因为SRAM 掉电后数据就丢失。
多数情况下SRAM 只是在调试时使用,也可以做其他一些用途。
如做故障的局部诊断,写一段小程序加载到SRAM 中诊断板上的其他电路,或用此方法读写板上的Flash 或EEPROM 等。
还可以通过这种方法解除内部Flash 的读写保护,当然解除读写保护的同时Flash 的内容也被自动清除,以防止恶意的软件拷贝。
STM32 PB2(BOOT1)使用注意由于STM32 PB2 脚是复用引脚,而且该复用功能是用于启动选择,使用时就要小心了。
-------------------------------------------------------------------------BOOT1 BOOT0 启动模式说明X 0 用户闪存存储器用户闪存存储器被选为启动区域0 1 系统存储器系统存储器被选为启动区域(进入ISP 模式)1 1 内嵌SRAM 内嵌SRAM 被选为启动区域-------------------------------- -----------------------------------------一般来讲我们正常使用是模式1(用户闪存存储。
ROM RAM Flash区别

ROM和RAM区别ROM(Read Only Memory,只读存储器)在系统停止供电的时候仍然可以保持数据,RAM(Random Access Memory,随机存取存储器)通常都是在掉电之后就丢失数据,典型的RAM就是计算机的内存。
ROM、PROM、EPROM、EEPROM区别ROM(Read Only Memory,只读存储器):生产过程中烧录程序,用户无法更改。
在微机的发展初期,BIOS都存放在ROM中。
ROM内部的资料是在ROM的制造工序中,在工厂里用特殊的方法被烧录进去的,其中的内容只能读不能改,一旦烧录进去,用户只能验证写入的资料是否正确,不能再作任何修改。
如果发现资料有任何错误,则只有舍弃不用,重新订做一份。
ROM是在生产线上生产的,由于成本高,一般只用在大批量应用的场合。
PROM(Programmable ROM,可编程ROM):用户可以烧录程序,但只能烧录一次。
由于ROM制造和升级的不便,后来人们发明了PROM。
最初从工厂中制作完成的PROM 内部并没有资料,用户可以用专用的编程器将自己的资料写入,但是这种机会只有一次,一旦写入后也无法修改,若是出了错误,已写入的芯片只能报废。
PROM的特性和ROM相同,但是其成本比ROM高,而且写入资料的速度比ROM的量产速度要慢,一般只适用于少量需求的场合或是ROM量产前的验证。
EPROM(Erasable Programmable ROM,可擦除可编程ROM):可重复擦除和写入,但操作不方便。
EPROM芯片有一个很明显的特征,在其正面的陶瓷封装上,开有一个玻璃窗口,透过该窗口,可以看到其内部的集成电路,紫外线透过该孔照射内部芯片就可以擦除其内的数据,完成芯片擦除的操作要用到EPROM擦除器。
EPROM内资料的写入要用专用的编程器,并且往芯片中写内容时必须要加一定的编程电压(VPP=12~24V,随不同的芯片型号而定)。
EPROM的型号是以27开头的,如27C020(8*256K)是一片2M Bits容量的EPROM芯片。
STM32片内FLASH特定地址写入数据不被擦除方法

STM32中存储区分为:随机存取存储器RAM和只读存储器ROM。
其中:RAM为常说的内存,比如手机的2G内存4G内存等,就是程序跑起来的时候所占用的存储空间,特点是掉电数据丢失。
ROM为常说的硬盘,比如手机的64G和128G等,可以简单的理解为硬盘的存储空间,特点是掉电数据不丢失,所以又叫“非易失性存储器件”。
ROM又包含:EEPROM和flash。
作为ROM的一份子,flash的特点自然是掉电数据不丢失。
但是,flash在STM32中比较重要,程序也是保存在这个地方,所以轻易不让用户进行随意的读写,以避免不必要的问题。
1、STM32 FLASH操作流程Flash操作已经属于嵌入式设备中很底层的操作了,直接对地址进行存取,简单描述,Flash操作大致需要以下流程:1、确定要写入Flash的首地址(稍后介绍确定地址的方法)2、解锁Flash3、对Flash进行操作(写入数据)4、对Flash重新上锁1.1 如何查找并选定要写入Flash十六进制地址值的方法要想选定安全的Flash地址进行读写,可以根据自己的STM32 MCU型号,查找数据手册,确定FLASH的地址区段,因为起始段会存储代码,所以一定要避开起始段,以避免数据错误。
(我一般是根据Flash大小计算Flash的最末尾地址,往前推一段地址空间,在这里一般不会对代码中的数据产生覆盖等影响)我此次操作Flash使用的MCU是STM32103C8T6,所以以该型号MCU为例进行描述:在数据手册中,可以看到STM32103C8T6的flash起始地址是0x0800 0000(如下图所示),而STM32103C8T6的Flash大小为64K,可以计算出STM32103C8T6的Flash地址范围是:0x0800 0000——0x0800 FFFF(计算方法参考另一篇博客:STM32内存大小与地址的对应关系以及计算方法)。
这里选取0x0800 F000作为读写操作的起始地址,对于C8T6这款MCU,操作这个起始地址应该算是很安全的范围了。
STM32 大小容量芯片之间的差别

STM32 大小容量芯片之间的差别
本文主要讨论STM32F103xC,STM32F103xD 和STM32F103xE 大容量增强型芯片的特性:1)何为大容量芯片呢?
答:高达512K 字节的闪存和64K 字节的SRAM 的芯片为大容量。
2)STM32 有分小容量,中等容量和大容量的型号,区别呢?
因为STM32F103xx 是一个完整的系列,其成员之间是完全地脚对脚兼容,软件和功能上也兼容。
在参考手册中,STM32F013x4 和STM32F103x6 被归为小容量产品,STM32F103x8 和STM32F103xB 被归为中等容量产品,
STM32F103xC,STM32103xD 和STM32F103xE 被归为大容量产品,其中我们的神舟II 号就是选择的STM32F103xC 芯片,神舟III 号是STM32xE 芯片,都是属于大容量产品,容量大一点,大家在做产品和项目时更具备参考性。
小容量和大容量产品是中等容量产品(STM32F103x8/B)的延伸,小容量
对应的数据手册为《STM32F103x4/6 数据手册》和《STM32F103xC/D/E 数据手册》。
小容量产品具有较小的闪存存储器,RAM 空间和较少的定时器和外设。
而
大容量的产品则具有较大的闪存存储器,RAM 空间和更多的片上外设,如SDIO,FSMC,I2S 和DAC 等,同时保持与其它同系列的产品兼容。
表:STM32F103xx 系列
3)规格说明
答:STM32F103xC,STM32F103xD 和STM32F103xE 型系列是32 位的RISC 内核,工作频率为72MHz,丰富的增强I/O 端口和联接到两条APB 总线的外设。
单片机的ROM与RAM

单片机的ROM与RAMROM:(Read Only Memory)程序存储器在单片机中用来存储程序数据及常量数据或变量数据,凡是.c文件及.h文件中所有代码、全局变量、局部变量、'const’限定符定义的常量数据、startup.asm文件中的代码(类似ARM中的bootloader或者X86中的BIOS,一些低端的单片机是没有这个)通通都存储在ROM中。
ROM按其性能可分为以下几类:(1)掩模工艺ROM它是由芯片制造厂根据ROM要求存储的信息,制造成固定的半导体掩模版生产的。
一旦制出成品后,其存储的信息只能读出,不能改变。
这种ROM适用于存储固定不变的程序和数据,批量生产时,成本较低。
(2)可一次编程PROM允许用户对ROM进行一次编程。
(3)可擦除的EPROM允许用户对ROM进行多次编程,即可擦除。
按擦除的方法不同,可分为紫外线擦除的可擦除可编程序只读存储器EPROM(Erasable Programmable Read Only Memory)和电擦除的电可擦除编程序只读存储器EEPROM(Electrically Erasable Programmable Read Only Memory)。
(4)Flash存储器Flash存储器是在20世纪80年代末逐渐发展起来的一种新型不挥发性半导体存储器,它结合了以往EPROM结构简单、密度高和EEPROM在系统的电可擦除性的一些优点,实现了高密度、低成本和高可靠性。
Flash存储器和传统存储器的最大区别在于它是按块(Sector)擦除,按位编程,从而实现了快闪擦除的高速度。
目前它广泛应用于PCBIOS、数字蜂窝电话、汽车领域和微控制器等许多领域。
EPROM、EEPROM、Flash存储器需通过专用的编程器将程序和数据写入其中。
RAM:(Random Access Memory)随机访问存储器用来存储程序中用到的变量。
凡是整个程序中,所用到的需要被改写的量,都存储在RAM中,“被改变的量”包括全局变量、局部变量、堆栈段。
stm32后备ram的保存原理

一、STM32后备RAM的概念STM32后备RAM是指STM32微控制器中的一块RAM,用于保存一些关键的系统参数和状态数据。
这些数据在断电或复位后仍能保持,以便系统在重新上电或复位后能够继续正常工作。
二、后备RAM的作用1. 保存系统参数:包括唯一设备标识符、校准参数、配置信息等。
2. 保存状态数据:包括定时器计数值、中断状态、运行状态等。
三、保存原理STM32后备RAM的保存原理主要依靠两种技术:低功耗保持器和后备寄存器。
1. 低功耗保持器低功耗保持器是一种非易失性存储器,能够在断电或复位后保持数据。
在STM32中,低功耗保持器一般采用电容或电池来实现。
当系统断电或复位时,低功耗保持器能够提供持续的电源供应,以保持后备RAM 中的数据不丢失。
2. 后备寄存器后备寄存器是指STM32芯片中专门用于保存后备RAM位置区域和数据的寄存器。
在系统正常工作时,通过特定的指令将需要保存的数据写入后备寄存器,并同时触发低功耗保持器将数据保存到后备RAM中。
而在系统断电或复位后,后备寄存器能够自动恢复数据到相应的寄存器中,以便系统能够在重新上电或复位后恢复数据。
四、存储机制STM32后备RAM的存储机制主要包括以下几个方面:1. 数据写入:在系统正常工作时,通过特定的指令将需要保存的数据写入后备寄存器,并触发低功耗保持器将数据保存到后备RAM中。
2. 数据读取:在系统重新上电或复位后,后备寄存器会自动读取后备RAM中的数据,并恢复到相应的寄存器中。
3. 保持时间:低功耗保持器能够在断电或复位后持续供电一段时间,一般能够保持数年不丢失数据。
五、应用场景1. 唯一设备标识符的保存:后备RAM中保存设备的唯一标识符,以便在系统重新上电或复位后能够继续识别设备。
2. 校准参数的保存:后备RAM中保存传感器的校准参数,以确保系统重新上电或复位后传感器依然能够正常工作。
3. 系统状态的保存:后备RAM中保存系统的运行状态和配置信息,以便系统重新上电或复位后能够恢复到上次的状态。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
按照上边的例子,在Keil中编译工程成功后,在下面的Bulid Ouput窗口中会输出下面这样一段信息:Program Size: Code=119222 RO-data=18266 RW-data=320 ZI-data=23492代表的意思:Code :是程序中代码所占字节大小RO-data :程序中所定义的指令和常量大小(个人理解:Read Only)RW-data :程序中已初始化的变量大小 (个人理解”:Read/Write)ZI-Data :程序中未初始化的变量大小 (个人理解:Zero Initialize)ROM(Flash) size = Code+RO-data+RW-data;RAM size = RW-data+ZI-data可以通过.map查看占用的flash和ram大小Code是代码占用的空间,RO-data是 Read Only 只读常量的大小,如const 型,RW-data是(Read Write)初始化了的可读写变量的大小,ZI-data是(Z ero Initialize)没有初始化的可读写变量的大小。
ZI-data不会被算做代码里因为不会被初始化。
简单的说就是在烧写的时候是FLASH中的被占用的空间为:Code+RO Data+RW Da ta程序运行的时候,芯片内部RAM使用的空间为:RW Data+ZI DataARM编译中的RO、RW和ZI DATA区段ARM程序(指在ARM系统中正在执行的程序,而非保存在ROM中的bin文件)的组成一个ARM程序包含3部分:RO段,RW段和ZI段RO是程序中的指令和常量RW是程序中的已初始化变量ZI是程序中的未初始化的变量由以上3点说明可以理解为:RO就是readonly,RW就是read/write,ZI就是zeroARM映像文件的组成所谓ARM映像文件就是指烧录到ROM中的bin文件,也成为image文件。
以下用Image文件来称呼它。
Image文件包含了RO和RW数据。
之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。
包含进去反而浪费存储空间。
Q:为什么Image中必须包含RO和RW?A:因为RO中的指令和常量以及RW中初始化过的变量是不能像ZI那样“无中生有”的。
ARM程序的执行过程从以上两点可以知道,烧录到ROM中的image文件与实际运行时的ARM程序之间并不是完全一样的。
因此就有必要了解ARM程序是如何从ROM中的image到达实际运行状态的。
实际上,RO中的指令至少应该有这样的功能:1. 将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。
2. 将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。
ZI中也是变量,同理:变量不能存在ROM中在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。
否则只能运行不含变量的代码。
说了上面的可能还是有些迷糊,RO,RW和ZI到底是什么,下面我将给出几个例子,最直观的来说明RO,RW,ZI在C中是什么意思。
1; RO看下面两段程序,他们之间差了一条语句,这条语句就是声明一个字符常量。
因此按照我们之前说的,他们之间应该只会在RO数据中相差一个字节(字符常量为1字节)。
Prog1:#include <stdio.h>void main(void){;}Prog2:#include <stdio.h>const char a = 5;void main(void){;}Prog1编译出来后的信息如下:===================================================================== ===========Code RO Data RW Data ZI Data Debug948 60 0 96 0 Grand Totals===================================================================== ===========Total RO Size(Code + RO Data) 1008 ( 0.98kB)Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)===================================================================== ===========Prog2编译出来后的信息如下:===================================================================== ===========Code RO Data RW Data ZI Data Debug948 61 0 96 0 Grand Totals===================================================================== ===========Total RO Size(Code + RO Data) 1009 ( 0.99kB)Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)Total ROM Size(Code + RO Data + RW Data) 1009 ( 0.99kB)===================================================================== ===========以上两个程序编译出来后的信息可以看出:Prog1和Prog2的RO包含了Code和RO Data两类数据。
他们的唯一区别就是P rog2的RO Data比Prog1多了1个字节。
这正和之前的推测一致。
如果增加的是一条指令而不是一个常量,则结果应该是Code数据大小有差别。
2; RW同样再看两个程序,他们之间只相差一个“已初始化的变量”,按照之前所讲的,已初始化的变量应该是算在RW中的,所以两个程序之间应该是RW大小有区别。
Prog3:#include <stdio.h>void main(void){;}Prog4:char a = 5;void main(void){;}Prog3编译出来后的信息如下:===================================================================== ===========Code RO Data RW Data ZI Data Debug948 60 0 96 0 Grand Totals===================================================================== ===========Total RO Size(Code + RO Data) 1008 ( 0.98kB)Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)===================================================================== ===========Prog4编译出来后的信息如下:===================================================================== ===========Code RO Data RW Data ZI Data Debug948 60 1 96 0 Grand Totals===================================================================== ===========Total RO Size(Code + RO Data) 1008 ( 0.98kB)Total RW Size(RW Data + ZI Data) 97 ( 0.09kB)Total ROM Size(Code + RO Data + RW Data) 1009 ( 0.99kB)===================================================================== ===========可以看出Prog3和Prog4之间确实只有RW Data之间相差了1个字节,这个字节正是被初始化过的一个字符型变量“a”所引起的。
3; ZI再看两个程序,他们之间的差别是一个未初始化的变量“a”,从之前的了解中,应该可以推测,这两个程序之间应该只有ZI大小有差别。
Prog3:#include <stdio.h>void main(void){;}Prog4:char a;void main(void){;}Prog3编译出来后的信息如下:===================================================================== ===========Code RO Data RW Data ZI Data Debug948 60 0 96 0 Grand Totals===================================================================== ===========Total RO Size(Code + RO Data) 1008 ( 0.98kB)Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)===================================================================== ===========Prog4编译出来后的信息如下:===================================================================== ===========Code RO Data RW Data ZI Data Debug948 60 0 97 0 Grand Totals===================================================================== ===========Total RO Size(Code + RO Data) 1008 ( 0.98kB)Total RW Size(RW Data + ZI Data) 97 ( 0.09kB)Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)===================================================================== ===========编译的结果完全符合推测,只有ZI数据相差了1个字节。