单片机的RAM和ROM
单片机的ROM,叫只读程序存储器,是FLASH存储器构成的,如U盘就是FLASH存储器。所以,FLASH和ROM是同义的。单片机的程序,就是写到FLASH中了。
而RAM是随机读/写存储器,用作数据存储器,是在运行程序时,存放数据的。
内存区
内存主要分为:代码区、常量区、静态区(全局区)、堆区、栈区这几个区域。
l 代码区:存放程序的代码,即CPU执行的机器指令,并且是只读的。
l 常量区:存放常量(程序在运行的期间不能够被改变的量,例如: 25,字符串常量”dongxiaodong”, 数组的名字等)
l 静态区(全局区):静态变量和全局变量的存储区域是一起的,一旦静态区的内存被分配, 静态区的内存直到程序全部结束之后才会被释放
l 堆区:由程序员调用malloc()函数来主动申请的,需使用free()函数来释放内存,若申请了堆区内存,之后忘记释放内存,很容易造成内存泄漏
l 栈区:存放函数内的局部变量,形参和函数返回值。栈区之中的数据的作用范围过了之后,系统就会回收自动管理栈区的内存(分配内存 , 回收内存),不需要开发人员来手动管理。栈区就像是一家客栈,里面有很多房间,客人来了之后自动分配房间,房间里的客人可以变动,是一种动态的数据变动。
STM32F103C8T6中
OM起始地址为:0x8000000, 大小为:0x10000 (64K)
只读的,存放着代码区和常量区
RAM起始地址为:0x20000000,大小为:0x5000 (20K)
可读可写的,存放着静态区、栈区和堆区
STM32各区详细介绍:
代码区:
l 代码区存放着程序编译后的CPU指令
l 函数名称是一个指针,可以通过查询函数名称所处的内存地址,查询函数存放的区域
//函数声明
void dong();
//主函数定义
int main(void)
{
//串口初始化
Uart1_Init(115200);
//函数调用
dong();
//输出test函数地址
printf("dong() addrs : 0x%p\n",dong);
while(1);
}
void dong(){
//输出main函数地址
printf("mian() addrs : 0x%p\n",main);
}
输出:
可见0x08000c2d和0x08000be9都在ROM里的代码区
常量区
指针可以指向常量也可以指向变量的区域,通过指针(char *p)来测试一下常量与变量去的地址变化。
void dongxiaodong_fun(){
char *p=NULL;//定义一个指针变量
//常量
p="2020dongxiaodong";//指针指向一个常量
printf("addr1:0x%p\r\n",p);//输出常量地址
//变量
char data[]={"dong1234"};
p=data;//指针指向一个变量
printf("addr2:0x%p\r\n",p);//输出变量地址
}
输出:
可见常量的地址在ROM里的常量区,局部变量在RAM的栈空间下
静态区
静态区包括静态变量和全局变量,静态变量通过static修饰,一旦初始化则一直占用RAM空间
int global_a;//全局变量,默认值为0
static int global_b;//静态全局变量,默认值为0
void fun(){
static int c;//静态变量,默认值为0
printf("static int c add