奇怪,往xdata的一个数组里写数,第0个元素的值会自动变成0,改成idata就不会出现

2020-01-23 14:50发布

小弟在做一个项目,往数组里边写入一个要显示的数据,送1602LCD进行显示。
定义的了一个在xdata区的数组:
xdata uchar ber[7];
然后某段程序往里边赋值
for(i=0;i<7;i++)
ber=array;
结果发现ber[0]的值被变成了十进制的0,导致LCD显示函数认为已经到了最后一个字符而不显示。
即使我把代码改成:
for(i=0;i<7;i++)
ber=i+ '0';//(变成asccii码)
一样的,就ber[0]的值为0,数组其他元素的值是对的。
后来干脆把ber[]定义在idata区内。
竟然没有问题了!
想不明白为什么。

一开始怀疑为xdata区的这一字节坏掉了。
坏了个新一点儿的片子也这样。
如果xdata区不稳定,应该不只这一字节坏掉,我其他还有很多定义在Xdata区域内的变量,也是正常的。就这一个不正常。
请教高手这是为什么。

一开始也怀疑过,data的某些区域会被中断占用,可是xdata区域是不会被占的丫!
我的data=198字节,XDATA=912字节,code=22334字节
XDATA是片内自带的1KB XRAM
WINBOND W77E58 52单片机
keil uv 8.03版

另外有一个问题不明白,如果编译器告诉我,data使用量不超过256字节,是不是代表data占用量不会受中断影响(我是说会不会由于中断导致data溢出)?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
52条回答
rainyss
1楼-- · 2020-01-23 16:26
data用量不超过256字节不代表你的内存仍够用,很多人喜欢函数套函数,一层层地套,甚至中断里头也是一堆函数调用,美其名曰"结构化",三两下就把堆栈堆满了,程序运行起来时不时地出点错,作BUG定位时根本找不到.

至于你碰到的问题,十有八九是你的程序工作不正常,最好能将代码发出来给大家看看,毕境大家都是上班族,没太多时间帮你瞎蒙,你说呢?
zhanliana
2楼-- · 2020-01-23 17:42
 精彩回答 2  元偷偷看……
flywater
3楼-- · 2020-01-23 19:45
你的程序从编译角度来看没任何问题,但导致你的程序与运行结果偏差的主要原因是因为XDATA的使用上出了问题,你不能完全信任 Keil 在Compiling时给你显示的信息,它说你用了912个XDATA,你完全相信它吗?不敢怀疑它?那你就只能出错了....

找一个你定义的XDATA数组来看看吧:

    //主程序160行处
    for(r=0;r<7;r++)
       strtointer[r]=0;
    for(r=0;r<30;r++)
       recvstring1[r]=0;

你在头文件里是这样定义的   
xdata        uchar        strtointer[7];    //字符转成整数,临时数组,第[0]个元素无效

编译结果:
assembling STARTUP.A51...
compiling rfsw.c...
linking...
Program Size: data=186.0 xdata=907 code=23298
creating hex file from "rfsw_snmp"...
"rfsw_snmp" - 0 Error(s), 0 Warning(s).

看一下它在XDATA内的绝对地址在哪?
  ;162:         for(r=0;r<7;r++)
C:0x3905    90046C   MOV      DPTR,#r(0x046C)
C:0x3908    F0       MOVX     @DPTR,A
C:0x3909    90046C   MOV      DPTR,#r(0x046C)
C:0x390C    E0       MOVX     A,@DPTR
C:0x390D    FF       MOV      R7,A
C:0x390E    C3       CLR      C
C:0x390F    9407     SUBB     A,#0x07
C:0x3911    5014     JNC      C:3927

给你定位到0x046C去了,超过1K了吧?电路中有外扩XRAM没?如果没有不出错才怪呢!
flywater
4楼-- · 2020-01-23 23:31
其它的就不用分析了,还有好几个数组定义在1K之外了,取出的数据自然也是就0了
zhanliana
5楼-- · 2020-01-24 00:57
感谢落叶的这么细心的帮我看代码,还给我这么详细的回复。感觉你们在应时的纯熟程度就像在用记事本写字一样,清晰了然,我们就像在使用word,永远搞不懂我们一个动作到底会带来什么样的结果。起码不是很明确地知道!

那追问下落叶,我如何才能避免这种情况的出现呢。
单片机自带的XRAM,为1KB大小。
只要让PMR=0x01 XRAM区就生效了。是不是要在keil里设置下,告诉他:
1 我要使用片内自带的XRAM;
2 XRAM的地址是从0x00到0x200;这样?
另外,如果我写的某个程序占用data达到256字节,会不会由于中断和堆栈等导致溢出?(排除编译器欺骗我的情况下),嘿嘿
aaa1982
6楼-- · 2020-01-24 03:17
为什么xdata=907

xdata会用到0x046C,xdata应该是从0x0000顺序往下分配的。到底是什么问题。还没碰到keil出错的情况,而且错的那么离谱。

一周热门 更多>