Keil 程序报错: ‘DATA‘: SEGMENT TOO LARGE 怎么办(Large情况下代码还报错),两种解决办法

 前言

        最近在写51单片机代码的时候,出现了 'DATA': SEGMENT TOO LARGE 的报错,本以为是程序太长就用了下面我讲的第一种网上一搜就可以搜到的解决办法,就是在点击魔法棒Target->Memory Model 中的值改为[Large:variables in XDATA ]就可以了,大多数情况用这种办法是可以的,但是我发现我的代码中有一个Small下可以正常运行但在Large下就不能运行了,我还以为真的是因为我程序太长了,难道真的要屈辱的把自己代码改短吗?笑,为了不浪费我写了那么长的代码,最终还是让我找到了解决的办法。


方法一

操作方法:

Keil 程序报错: ‘DATA‘: SEGMENT TOO LARGE 怎么办(Large情况下代码还报错),两种解决办法_第1张图片

      这种方法治标不治本,但是在大多数情况下应该是够用的,只要你的程序能正常运行,用这种方法应该也不是不行。毕竟相比下面那种方法,它实在是简单粗暴多了。

 

方法二

操作方法:

原因分析:
        “Keil C51编译器提供三条编译模式控制命令:SMALL,COMPACT,LARGE,它们会对变量存储器空间产生影响。

Small 所有变量都被定义在8051单片机的片内RAM中,对这种变量的访问速度最快。另外,堆栈也必须位于片内RAM中,而堆栈的长度是很重要的,实际栈长取决与不同函数的嵌套深度。采用SMALL编译模式与定义变量时指定data存储器类型具有相同效果。
Compact 所有变量被定义在分页寻址的片外XRAM中,每一页片外XRAM的长度为256字节。这时对变量的访问是通过寄存器间接寻址(MOVX @R0,MOVX @R1)进行的,变量的低8位地址由R0和R1确定,变量的高8位地址由P2口确定。采用这种模式时,必须适当改变配置文件STARTUP.A51中的参数:PDATASTART和PDATALEN;同时还必须对uVision2的“Options选项/BL51 Locator 标签页/Pdata框”中键入合适的地址参数,以确保P2口能输出所需要的高8位地址。采用COMPACT编译模式与定义变量时指定pdata存储器类型具有相同效果。
Large 所有变量被定义在片外XRAM中(最大可达64KB),使用数据指针DPTR来间接访问变量(MOVX @DPTR),这种编译模式对数据访问的效率最低,而且将增加程序的代码长度。采用LARGE编译模式与定义变量时指定xdata存储器类型具有相同效果。”

      虽然看了之后还没看太懂是什么意思,但是不重要,写单片机程序遇到'DATA' SEGMENT TOO LARGE,data是直接寻址的片内RAM区低128B(00H~7FH),说明128字节的data数据空间已经用完。注意是数据空间,其实也就是变量,参数这些的了,这时我们只需要把原本放在data中的一部分数据(变量)放到别的地方即可。

根据数据的用处,可以有以下几种选择:

bdata:片内RAM的可位寻址区(20H~2FH),允许字节和位混合访问

idata:单片机间接访问的片内RAM区,允许访问全部片内RAM

pdata:Ri间接访问的片外RAM的低256B(00H~FFH)

xdata:用DPTR间接访问的片外RAM,允许访问全部64KB片外RAM(0000H~FFFFH)

code:单片机的64KB程序存储区ROM

        虽然上面这几个选项还是没看太懂,但是我看懂了一点我把程序在Large下编译成功的信息:

933947d21c4f4df6bc52a6f38007eea5.png

        既然Large下只显示了data,xdata,code,整整三个选项,那我就选择xdata 好了!

xdata uchar RecBuf[15];
xdata uchar RecNum=0;
xdata int price[]={1,2,3,4,5};
xdata int price_type=1;
xdata uchar* kg_g[]={"Kg","g"};
xdata int kg_g_index=1;
xdata uchar* str_week[] = {"一","二","三","四","五","六","日"};
xdata uchar robot[] = {0x30,0x0C,0x48,0x12,0x50,0x0A,0x28,0x14,0x04,0x20,
	0x1F,0xF8,0x30,0x0C,0x76,0x6E,0x71,0x8E,0x34,0x2C,0x13,0xC8,0x10,
	0x08,0x0F,0xF0,0x03,0xC0,0x00,0x00,0x00,0x00};

        具体的设置方法就如同上面的操作,但是最好是只将自己定义的变量变成xdata,尤其是要注意不要把只能在Small下运行的代码块中的变量给xdata了,这样改好后我们的代码就可以在Small下运行了。

Keil 程序报错: ‘DATA‘: SEGMENT TOO LARGE 怎么办(Large情况下代码还报错),两种解决办法_第2张图片

       这是我在Small 下编译成功的长达1776 行的0 Errors ,0 Warnings 的代码。

       最后,如果觉的这篇文章对你有用的话记得点个赞让更多的人能够得到看到哟。

 

 

你可能感兴趣的:(bug记录,C51单片机学习笔记,c语言,51单片机)