首页 > 其他分享 >【STC15】内部RAM讲解(data/idata/xdata的区别)

【STC15】内部RAM讲解(data/idata/xdata的区别)

时间:2024-08-28 21:38:31浏览次数:12  
标签:idata 字节 STC15 RAM 寄存器 全局变量 data 工作组

简短不看版

  • 空间分配先使用data,data不够再用idata,idata使用时要预留22个字节以上的空间进行压栈,idata不够再使用xdata,这样的程序效率是最高的
  • 在1T的模式下,程序运行速度比12T的快很多,压22个字节和6个字节效率差不太多,如果不是很熟练,少用using,如果熟练了,可以使用using优化
  • 多去project.m51文件查看内存分配情况,尽量把前面的空间用完再用后面的,不要浪费

 

STC15 SRAM内部分配情况、idata/xdata的概念

图 stc15 SRAM和ROM的空间分配情况

keil编译成功时显示的data、xdata、code

  • data就是片内RAM低128字节的区域
  • idata就是包括低128字节的总256字节的区域
  • xdata:如果片内有拓展的xdata就指片内拓展的部分,如现在使用的单片机型号,如果没有拓展,一般是片外RAM
  • code是ROM程序存储器

程序编译成功时会在信息框内显示data、xdata、code各被占了多少字节,keil工具可以设置变量默认放在哪个存储区,默认是data

写代码时,可以在变量前面加关键字指定存放区域,先默认放data里,不够用了再放idata里,再不够用就放xdata里,即,:

  • 优先级:data > idata > xdata
  • 速度:data > idata > xdata

堆栈空间不足的情况

假如程序太大,使用完了idata的空间,如图所示,使用到了00FFH,这说明已经没有空间进行压栈操作了,这种程序是有隐患的,keil软件能正常编译通过,但运行时单片机只要进入中断需要压栈时就出问题了,可能会导致死机;即使使用using指定工作组,在不嵌套中断情况下,也至少要3个字节空间进行压栈

所以编写程序时要尽量留够空间给压栈使用,如果使用默认工作组,则要22个字节以上,指定其他工作组的话,则要3(PC)+3(PSW) = 6个字节以上,即256 - 22 = 234,程序编译后data最多不超过234字节;

这对产品的稳定性来说很重要,如果不够22个字节以上,不进行中断嵌套测试就看不出问题,进行中断嵌套后就会出问题了;

使用32则不存在这种问题,用51就会有

 

在project.m51文件中,可看到堆栈所需空间的大小

STACK标志就表示堆栈,0022H表示程序已经使用到的RAM空间,片内RAM共256字节,00FFH - 0022H = 00DDH,剩余的空间00DDH就是给压栈使用的,因为上面工作组压栈时说明了,如果使用默认的工作组,加上PC和PSW则共要压11个字节,又因为中断是可以嵌套的,嵌套时要再压11个字节,这里就需要22个字节了,所以要确保空间比22个字节大,万一要嵌套,可确保空间够用,这里的00DDH是明显够用的。

 

工作组的概念

图 工作组与内部低128字节RAM

可以在中断处理函数后使用using指定工作组, 如:

void Timer0_isr() interrupt 1 using 1	//指定中断处理函数使用工作组1
{
    ……
}

在片内RAM的低128字节区域中,有4个工作组,程序默认是使用工作组0的

工作寄存器组区地址从00H ~ 1FH共32B(字节)单元,分为4组(每一组称为一个寄存器组),每组包含8个8位的工作寄存器,编号均为R0~R7,但属于不同的物理空间。通过使用工作寄存器组,可以提高运算速度。R0 ~ R7是常用的寄存器,提供4组是因为1组往往不够用。程序状态字PSW寄存器中的RS1和RS0组合决定当前使用的工作寄存器组。在程序的中断处理函数后面用using指定工作组,相当于置位PSW寄存器中的RS1和RS0位

当发生中断时,如果使用默认的工作组0,则R0 ~R7、PC指针和PSW程序状态字寄存器都需要一起压栈

  • PC指针(占16位,共2个字节)
  • PSW(程序状态字寄存器,占8位,共1个字节)
  • R0 ~ R7(共8个8位的工作寄存器,8个字节)

所以加起来就一共要压11个字节。如果不使用默认的,改为其他工作组,则不需要将R0 ~R7压栈,就只需压PC指针和PSW寄存器就行,共3个字节。

区别:

  • 压栈的字节越小,对堆栈的空间要求就越低,因为总空间256字节,堆栈空间小,在测试中断嵌套等情况时内存空间足够使用
  • ​压栈的字节越小,则压栈速度越快

程序演示:

//1. 在串口中断函数中不指定工作组,默认使用工作组0
void Usart_Rountine() interrupt 4
{
}

//2.  用using 1指定中断处理函数使用工作组1
void Usart_Rountine() interrupt 4 using 1
{
}

第1种情况:编译后,查看project.m51文件,只有工作组0

第2种情况:编译后再次查看project.m51文件,同时有了工作组0和工作组1

 

扩展:C51 全局变量 保存在哪里

C51全局变量默认保存在RAM中。

在C51编程中,全局变量的存储位置是在RAM中为其指定一个专用地址。这是因为全局变量在程序中可能会被频繁访问和修改,因此需要将其存储在RAM中以便快速访问。具体来说,全局变量被定义在内存中的专门地址上,其存储位置是固定的。这种存储方式适用于那些频繁存取且对程序运行至关重要的重要变量,尽管这样做可能会增加内存消耗并降低数据安全性。此外,全局变量的定义如果过多或者不当,可能会导致内存空间的浪费,处理速度变慢,同时数据安全性也会降低‌12。

C51编译器为全局变量分配的内存地址与局部变量的存储方式不同。局部变量通常被分配到寄存器组R0R7中,而全局变量的地址则存储在RAM的前128字节中‌3。这种区分体现了C51编程中对内存管理的精细控制,以确保程序的高效运行和数据的安全访问。

 

C51中可以指定变量存储在具体的存储器区域内:例如片内RAM、片外RAM、或者是ROM里。例如:char data test = 'c'; 定义test变量存储在直接寻址的内部RAM区。

具体的存储区域如下表:存储类型存储区域

  • data片内直接寻址RAM
  • idata片内间接寻址RAM
  • pdata分页寻址的片外RAM
  • xdata片外数据存储
  • code片内统一编址ROM
  • bdata片内可位寻址的RAM(128位)

扩展:ARM架构 全局变量 保存在哪里

STM32的全局变量通常保存在SRAM中。‌这是因为SRAM是易于访问和修改的存储器类型,并且可以提供较快的读写速度。

全局变量包括:

  • 已经初始化的全局变量和静态变量,它们存放在.data段
  • 未初始化的全局变量和初始化为0的静态变量则存放在.bss段中。

.data 段和.bss段的区别:是否占用可执行文件空间

.bss段不占用可执行文件空间,其内容由操作系统初始化。而.data段占用可执行文件空间,其内容由程序初始化。

此外,const定义的全局变量存放在Flash中,这是因为Flash中的数据是只读的,不可修改。通过这种方式,当定义不需要修改的变量时,可以使用const进行定义,从而节省RAM空间‌。

 

参考文章:

1. STC15单片机内部RAM讲解 https://blog.csdn.net/weixin_46251230/article/details/126603514

2.C51变量的设置和标准C语言,C51变量 https://blog.csdn.net/weixin_42528780/article/details/117062765

3.STM32寄存器 https://blog.csdn.net/Giii1/article/details/124939033

标签:idata,字节,STC15,RAM,寄存器,全局变量,data,工作组
From: https://www.cnblogs.com/FBsharl/p/18385571

相关文章

  • Hitachi Vantara Programming Contest 2024(AtCoder Beginner Contest 368)F - Dividing
    https://atcoder.jp/contests/abc368/tasks/abc368_f#include<bits/stdc++.h>#definexfirst#defineysecondusingnamespacestd;typedeflonglongll;typedefpair<ll,char>pii;constintN=2e5+10,inf=1e9;lln,m,k;intb[N],sg[N],a[N];vector......
  • 深入解析Pandas的Series与DataFrame索引和切片操作(三)
    Pandas库是Python中用于数据处理和分析的强大工具,它的核心数据结构包括Series和DataFrame。掌握Pandas的索引与切片操作是数据分析的基础,因为它们允许我们高效地访问、筛选和操作数据。本文将详细介绍Pandas中的Series和DataFrame的索引与切片方法,帮助你更好地理解和应用这......
  • Atcoder [AGC006D] Median Pyramid Hard 题解 [ 紫 ] [ 二分 ] [ adhoc ]
    MedianPyramidHard:二分trick加上性质观察题。trick我们可以二分值域,然后把大于等于它的数标记成\(1\),其他标记为\(0\)(有些题需要标记成\(-1\)),然后根据这个来check方案是否可行,这通常通过判断某个数是否是\(1\)来实现。本质上其实就是check大于等于它的数能否成为......
  • 高通ramdump
    背景高通平台下提供了一个工具,专门用来抓取内核死机以后的dump信息。如果只是非系统层面的crash(例如底层应用,安卓程序),则不能抓取dump信息。在阅读一些文档的时候知道有这个功能,但是一直没时间尝试。介绍流程为:1、进入dump模式:系统需要触发crash,同时机器需要进行warmreset2......
  • stm32F4系列 CCM_RAM使用
    stm32F4系列CCM_RAM使用使用方法1、这种情况下,所有管理工作都是编译来处理的,不方面用户将变量定义到指定的CCM或者SDRAM中。而使用__attribute__指定具体地址又不方便管理。针对这种情况,使用一个脚本文件即可解决,脚本定义如下:;*************************************......
  • uiotos和iframe有什么区别?
    尽管都能嵌套,UIOTOS主要是界面嵌套,而iframe是网页嵌套。其他多个方面存在显著的区别,以下是对两者主要区别的详细对比:1.定义与用途UIOTOS:UIOTOS是一款无需编程的前端开发工具,通过独特的专利技术,帮助非开发者快速定制复杂的WEB应用。它专注于解决前端界面开发定制难题,提供常......
  • 除了iframe,不用写代码还有什么办法实现界面嵌套?
    除了iframe,不用写代码实现界面嵌套的方法相对有限,但以下是一些可能的选择:1.使用可视化网站构建器可视化网站构建器(如Wix、Squarespace等)允许用户通过拖拽界面元素来创建和编辑网页,这些平台通常提供了一些基本的嵌套功能,比如通过容器组件将多个模块组合在一起,形成嵌套结构。用户......
  • uiotos和iframe在嵌套上的区别?
    UIOTOS与iframe在嵌套方面的对比区别主要体现在技术实现、功能整合、开发效率及维护性等多个方面。1.技术实现UIOTOS:UIOTOS通过其独特的页面嵌套技术,允许用户将不同的页面或组件无缝地集成在一起。这种嵌套不仅仅是界面上的整合,更重要的是实现了功能上的深度融合。UIOTOS支......
  • JavaScript 程序寻找通过 2 个点的线(Program to find line passing through 2 Points)
              在数学和计算机科学中,找到通过两个点的线的方程是一个基础问题。假设我们有两个点 P1​(x1​,y1​) 和 P2​(x2​,y2​),我们想要找到通过这两个点的直线方程。直线方程的形式直线的方程通常表示为 y=mx+b,其中 m 是斜率,b 是 y 轴截距。计算斜率......
  • C# 程序寻找通过 2 个点的线(Program to find line passing through 2 Points)
              在数学和计算机科学中,找到通过两个点的线的方程是一个基础问题。假设我们有两个点 P1​(x1​,y1​) 和 P2​(x2​,y2​),我们想要找到通过这两个点的直线方程。直线方程的形式直线的方程通常表示为 y=mx+b,其中 m 是斜率,b 是 y 轴截距。计算斜率......