解决keil单片编程ERROR L107: ADDRESS SPACE OVERFLOW问题及根源分析
1、将部分声明的不需要修改的变量声明为程序存储器变量,即在变量名前增加code关键字,如:
unsigned char code led_mod[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
当然,我们也可以使用关键字xdata将数据存储到片外存储器中去(如果我们不加任何关键字,就相当于默认使用了data关键字,也就是默认使用的是片内数据存储器)
2、修改存储器模式
对于代码行数比较多,程序运行空间需求大的程序,可能也会出现内存溢出的错误。但这个不是数据存储器的问题,而是程序存储器问题。程序存储器是用来供编译器控制指令small,compact和large指定编译时的存储器模式。
但是我自己测试 发现一个问题:
2.1如果把东西都放在PDATA
则不管是unsigned char 还是unsigned int全局变量,只要没有赋初值,大多都是默认为最大值,少量为随机数
2.2如果把东西都放在XDATA
总之就是可变的变量,不初始化放在PDATA或XDATA,则默认值都不正常(理论上应该全局变量不初始化,默认为0)。
3.放在data区
就正常了。
所以,我总结为,如果要改成XDATA,PDATA可变变量就都记得赋初值。
如果是DATA模式,则我们把不需要修改的变量声明为程序存储器变量(即在变量名前增加code关键字),以达到减少空间。如:
查看代码
code unsigned char led_mod[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
code unsigned char mode1[] = {0X01,0X02,0X04,0X08, 0X10,0X20,0X40,0X80}; //L1-L8
code unsigned char mode2[] = {0X80,0X40,0X20,0X10, 0X08,0X04,0X02,0X01}; //L8-L1
code unsigned char mode3[] = {0X81,0X42,0X24,0X18}; //两边向中间
code unsigned char mode4[] = {0X18,0X24,0X42,0X81};
code的作用就是告诉单片机,定义的数据要放在ROM(程序存储区64KB)里面,写入后就不能再更改,因为C语言中没办法详细描述存入的是ROM还是RAM(寄存器),所以在软件中添加了这一个语句起到代替汇编指令的作用,对应的还有data(128B)是存入RAM的意思。
关键词的意思:
code :程序存储区(64KB),
data :可直接寻址的内部数据存储区(128B)
idata:间接寻址的内部数据存储区(256B),Indirect addressing
bdata:可位寻址内部数据存储区(16B),Bitable internal data
xdata:外部数据存储区(64KB),External data store
pdata:分页的外部数据存储区,Pagination addressing
Keil C51中code、data、bdata、idata、xdata、pdata的解释点击跳转