打印
[其它应用]

SH79F9202 Keil C51报错提示内存空间已经不够用(DATA/PDATA/XDATA)

[复制链接]
2642|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-6-3 10:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
问题/报错:

*** ERROR L107: ADDRESS SPACE OVERFLOW
SPACE: DATA
SEGMENT: ?DT?UART
LENGTH: 0034H










Small:variables in DATA
Compact:variables in PDATA
Large:variables in XDATA
说明data空间已经不够用,原因是你可能有好多函数,而函数内部的局部变量又没有定义其空间,这种情况下,系统会将变量分配到你在Otions for Target 对话框里的设置的空间。如果你在下图所示中的 Memory Model 里设置成 Small:variables in DATA,则DATA空间很快便用完,导致data空间不够用。解决的办法有两种,一是通过更改Memory Model设置,可以设置成pdata或xdata,以便有足够大的空间,但这又带来新的问题,程序运行速度减慢,而且code代码也会加大,因为如果一个局部变量被存放在了xdata空间,汇编语言访问xdata空间的代码大小要比访问data空间的代码大,变量一旦很多,程序的代码也会逐渐增大;二是根据自己的要求设置变量的空间。所以这涉及到代码优化的问题,遇到具体问题时,在运行速度和代码大小之间取得适合自己的情况。



在 Keil C51 编译器中,内存模型(memory model)决定了变量的默认存储区。根据你的描述:

Small model: 默认将所有变量放在 DATA 区。
Compact model: 默认将所有变量放在 PDATA 区(Paged Data Memory)。
Large model: 默认将所有变量放在 XDATA 区(External Data Memory)。
以下是对每种内存模型的详细说明以及如何在 Keil C51 中使用它们。

Small Model
在 Small 内存模型中,所有变量默认存储在 DATA 区。DATA 区是8051微控制器的内部数据存储区,通常只有128字节或256字节。

配置 Small Model
在 Keil C51 中,你可以在项目设置中选择 Small 内存模型:

打开项目选项(Project Options)。
选择 “Target” 选项卡。
在 “Memory Model” 中选择 “Small”.
示例
// small_model.c
unsigned char smallVar;  // 默认存储在 DATA 区

void main(void) {
    smallVar = 0x55;
    while (1) {
        // 主循环
    }
}


Compact Model
在 Compact 内存模型中,所有变量默认存储在 PDATA 区。PDATA 区是片外分页数据存储区,通常是外部存储器的一部分,可以使用8位地址寻址。

配置 Compact Model
在 Keil C51 中,你可以在项目设置中选择 Compact 内存模型:

打开项目选项(Project Options)。
选择 “Target” 选项卡。
在 “Memory Model” 中选择 “Compact”.
示例
// compact_model.c
unsigned char compactVar _pdata;  // 显式声明存储在 PDATA 区

void main(void) {
    compactVar = 0xAA;
    while (1) {
        // 主循环
    }
}


Large Model
在 Large 内存模型中,所有变量默认存储在 XDATA 区。XDATA 区是片外扩展数据存储区,通常是外部存储器的一部分,可以使用16位地址寻址。

配置 Large Model
在 Keil C51 中,你可以在项目设置中选择 Large 内存模型:

打开项目选项(Project Options)。
选择 “Target” 选项卡。
在 “Memory Model” 中选择 “Large”.
示例
// large_model.c
unsigned char largeVar _xdata;  // 显式声明存储在 XDATA 区

void main(void) {
    largeVar = 0xFF;
    while (1) {
        // 主循环
    }
}


手动指定存储区
即使在指定了内存模型后,你仍可以手动指定单个变量的存储区,这对于需要特定内存布局的情况非常有用。

示例
// manual_memory.c
unsigned char smallVar _data;     // 存储在 DATA 区
unsigned char compactVar _pdata;  // 存储在 PDATA 区
unsigned char largeVar _xdata;    // 存储在 XDATA 区

void main(void) {
    smallVar = 0x01;
    compactVar = 0x02;
    largeVar = 0x03;
    while (1) {
        // 主循环
    }
}


通过配置内存模型和手动指定存储区,可以有效地管理8051微控制器的内存使用,避免地址空间溢出和优化程序性能。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/Naiva/article/details/139376007

使用特权

评论回复
沙发
caigang13| | 2024-6-3 19:29 | 只看该作者
地址存储空间溢出了

使用特权

评论回复
板凳
chenjun89| | 2024-6-4 08:15 | 只看该作者
数据溢出了,存储空间有限。

使用特权

评论回复
地板
powerantone| | 2024-6-4 15:58 | 只看该作者
优化代码

使用特权

评论回复
5
jcky001| | 2024-6-24 11:25 | 只看该作者
使用外部 RAM

使用特权

评论回复
6
cr315| | 2024-6-24 19:00 | 只看该作者
如果你的程序中有一些变量使用了过多的内存,考虑是否可以使用更小的数据类型,例如将 int 替换为 char 或 short。

使用特权

评论回复
7
tpgf|  楼主 | 2024-6-25 08:58 | 只看该作者
cr315 发表于 2024-6-24 19:00
如果你的程序中有一些变量使用了过多的内存,考虑是否可以使用更小的数据类型,例如将 int 替换为 char 或  ...

我觉得这样做在一些情况下是可以的 但是得看数据类型符合不符合应用场合

使用特权

评论回复
8
renzheshengui| | 2024-6-25 19:19 | 只看该作者
这个控制器看着就是专门控制 lcd的  应该程序代码不会很大才是

使用特权

评论回复
9
wakayi| | 2024-6-25 20:29 | 只看该作者
LCD ram只能给LCD控制使用吗

使用特权

评论回复
10
wowu| | 2024-6-25 21:39 | 只看该作者
如果是超出的范围比较多的话怎么解决呢

使用特权

评论回复
11
xiaoqizi| | 2024-6-25 22:49 | 只看该作者
优化一下程序的结构也能达到一定的效果

使用特权

评论回复
12
木木guainv| | 2024-6-25 23:59 | 只看该作者
这个内存空间是指的堆空间还是栈空间啊

使用特权

评论回复
13
菜鸟的第一步| | 2024-6-26 16:30 | 只看该作者
提高一下代码优化等级效果最明显

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1931

主题

15612

帖子

12

粉丝