奇怪,往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条回答
flywater
1楼-- · 2020-01-26 14:03
你用的是大模式编译,即编译器会把变量都放在XDATA内,而你又开了1K的显示缓冲,使用XDATA肯定超过1K了,而这片子只有1024的XRAM,所以要出错了
maidilong
2楼-- · 2020-01-26 17:08
呵呵~~~我解决了,我定义的二维数组是uchar buf[8][128]  编译的时候说太大了,编译不过去,于是我把存储模式改成large Xdata,这样就能编译过去了,但是只要一用这个二维数组显示就会乱,现在的解决方法是把二维数组改为uchar xdata buf[8][128] 就可以使用了,哈哈~~谢谢!1
flywater
3楼-- · 2020-01-26 22:37
回复【20楼】maidilong
呵呵~~~我解决了,我定义的二维数组是uchar buf[8][128]  编译的时候说太大了,编译不过去,于是我把存储模式改成large xdata,这样就能编译过去了,但是只要一用这个二维数组显示就会乱,现在的解决方法是把二维数组改为uchar xdata buf[8][128] 就可以使用了,哈哈~~谢谢!1
-----------------------------------------------------------------------

不要轻易用大模式编译,51的速度本来就不敢恭维。
另:恭喜!这么快解决了...
zhanliana
4楼-- · 2020-01-27 01:12
 精彩回答 2  元偷偷看……
flywater
5楼-- · 2020-01-27 02:52
自己写的程序,全靠别人找错是不现实的,因为每个人都有自己的工作,再则没硬件环境,具体情况也不好搞清楚,因为一些变量及输入值无法确定,程序分枝也不确定,而且完全读懂别人的程序并能帮助治疗一些顽症更不容易,所以即便坛里高手很多,也未必会给你回复,因为没太多空闲时间看程序并找错---工程师最头疼的就是找BUG....

以下这段程序思路上有点问题:

while(recvstring1[r]!='|')                //读取分隔符前边的数据
{
    if(recvstring1[r]!='.')
       strtointer[w]=recvstring1[r]-'0';
    else
      strtointer[w]='.';
      r++;
      w++;
} //指针往后移
level=caculate(w); //字符串转整型
.......
while(recvstring1[r]!='#')
{
    ber[w]=recvstring1[r] ;
    //ber[w]=w+'0';
    r++;
    w++;
}

这些循环未对数组是否越界进行检测,而且我调试过程中未在recvstring1中找到所谓的“|”或“#”,是不是没考虑接收字符串中无特定离符的情况?

程序不大,建议看仔细点,锻炼一下排错能力....只有你现在具备排错的最优越条件
zhanliana
6楼-- · 2020-01-27 07:37
其实我看了很多遍了。recvstring1[]是在串口接收中断中接收到另一个仪器传回的数据,以"&" 代表开头,"|"代表间隔 "#"代表结束。我的串口中断程序会每个字节中断,等到接收到结束标志,会置一个标志位,在大循环里边处理,并且按照间隔将数据读出来。
主程序里有问题的可能性不大。反复对比,发现只要改ber[]从XDATA区改到内部RAM区就没问题了。理论上讲,不改也应该没问题的。所以一直想不通。产生这一情况的原因可能有哪些。
keil和51单片机都这么多年了,不大可能有这么简单的BUG;
可能,随便放弃对这个问题的追究确实又不甘心。因为这个问题现象如此简单而明了。
仍然期待高手参与,进行研究。
顶起,以便高手能够看到。

一周热门 更多>