打印

为什么我的一个C51全局变量被莫名改变了?

[复制链接]
5880|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
happystar|  楼主 | 2007-11-30 19:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序编译结果如下:
Program Size: data=16.7 xdata=462 code=31803
creating hex file from "panel_disp"...
"panel_disp" - 0 Error(s), 0 Warning(s).
这个片子有256RAM和4K XRAM。
所以我定义变量的时候大多定义为xdata了。

在程序单步调试过程中发现:我定义的一个数据ct_once(在FLASH里存储的一个数据,它的值是通过面板设置的),在程序开始的时候它为1,当程序走到语句《1》后,ct_once就变成0了。
      compare_value[0] = 0x12ab;
      compare_value[1] = 0x34cd;
《1 》compare_value[2] = 0x56ef;
其中ct_once和compare_value[n]都是定义为xdata。
我把这几个变量都定义为volatile也不可以的。
而我把compare_value[n]定义为data就可以了。
实在不知道为什么呀?请教大家,
还有什么好的方法没有呢?


相关帖子

沙发
john_light| | 2007-12-1 08:34 | 只看该作者

不好说,芯片的XRAM使能了吗?

外部地址空间有没有其它的外设?会不会是地址重叠了?

链接器分配给数组的地址有没有超过芯片自带的4k?

使用特权

评论回复
板凳
ayb_ice| | 2007-12-1 09:26 | 只看该作者

指针是否有乱指呢

使用特权

评论回复
地板
1加1等于几| | 2007-12-1 11:48 | 只看该作者

111

使用特权

评论回复
5
happystar|  楼主 | 2007-12-1 11:52 | 只看该作者

thanks

re john_light:我用C8051F340,我的外部地址空间没有其他外设。你的意思是不是我应该设置一下外部存储器接口EMI0CN和EMIOCF寄存器呢?
re ayb_ice:在我的程序中也反复看了好些编,实在找不出指针乱指的地方。嘿嘿,以后再看看,暂时先排除这个假设吧。
看的出ayb_ice使用C8051F是高手,还望指导,谢谢

使用特权

评论回复
6
ayb_ice| | 2007-12-1 14:08 | 只看该作者

我有个340的开发板

用来学习USB的时候,没有什么问题啊。
复位默认的是内部XRAM,340有外扩功能吗,我好象不知道啊。
compare_value,ct_once在什么地方定义的。
”我定义的一个数据ct_once(在FLASH里存储的一个数据,它的值是通过面板设置的),在程序开始的时候它为1“
FLASH里数据可以随便改吗?

使用特权

评论回复
7
john_light| | 2007-12-1 14:53 | 只看该作者

查编译链接生成的过程文件

看两个变量分别被分配了什么地址

另外,在程序中增加输出两个变量值的指令:如从串口输出

然后全速运行看是不是真的被修改了

使用特权

评论回复
8
happystar|  楼主 | 2007-12-1 15:19 | 只看该作者

re

to ayb_ice:
”我定义的一个数据ct_once(在FLASH里存储的一个数据,它的值是通过面板设置的),在程序开始的时候它为1“
FLASH里数据可以随便改吗?"
1、它是个系数,它存储在flash里,上电要把它从flash里读出来,并送值给全局变量ct_once。在程序运行过程中,可以通过面板来设置它,然后通过复位程序,把修改好的ct_once重新覆盖存储。
2、compare_value[n],我也是定义的本文件中全局变量,一共有2个函数可以修改它的。
340也做过16C554扩展串口程序的。

to john_light:我在KC3里单步调试可以看到这个数据的值的变化("watch and call stack windows"),所以也用不着串口输出.可以看出运行完compare_value[2] = 0x56ef;ct_once就变为0了。
而我把ulong xdata compare_value[2];
改为  ulong data  compare_value[2];就OK了,不知道为什么

使用特权

评论回复
9
happystar|  楼主 | 2007-12-1 15:53 | 只看该作者

re john_light

john_light请看,我在.M51里复制过来的
方法1、如下定义这两个全局变量:(运行结果不正确的)
ulong     xdata compare_value[2];
uint     xdata ct_once; 
编译后结果:
Program Size: data=16.7 xdata=436 code=31331
creating hex file from "panel_disp"...
"panel_disp" - 0 Error(s), 0 Warning(s).

.M51结果:
  X:0136H         PUBLIC        compare_value
  X:013EH         PUBLIC        ct_once
方法2、如下定义这两个全局变量:(运行结果正确的)
ulong     data compare_value[2];
uint     xdata ct_once; 
编译后结果:
Program Size: data=24.7 xdata=428 code=31053
creating hex file from "panel_disp"...
"panel_disp" - 0 Error(s), 0 Warning(s).
.M51结果:
  D:0008H         PUBLIC        compare_value
  X:0136H         PUBLIC        ct_once

请john_light帮我看看方法1为什么ct_once会变




使用特权

评论回复
10
sharks| | 2007-12-1 16:12 | 只看该作者

看反汇编,在汇编中单步跟踪

  另外,看看有没有中断里面函数重入

使用特权

评论回复
11
mapleyang| | 2007-12-1 16:25 | 只看该作者

很简单

你定义的数组只有两个long型数据,而你对compare_value[2]操作,该处放着ct_once,能不被改动嘛。
好好想想C语言里数组的概念

使用特权

评论回复
12
happystar|  楼主 | 2007-12-1 16:59 | 只看该作者

晕菜!

是我误导大家!john_light,ayb_ice,sharks真不好意思,和你们绕了这么大的弯子,向你们道歉了。
谢谢mapleyang。
引用一下:
一、数组的声明
    声明数组的语法为在数组名后加上用方括号括起来的维数说明。本接仅介绍一维数组。下面是一个整型数组的例子:
        int array[10];
    这条语句定义了一个具有10个整型元素的名为array的数组。

我的ulong compare_value[2]其实只有2个数组(compare_value[0]compare_value[1]),compare_value[2]其实是不合法的(但是编译器不报错)。
刚才在TC下演示了一把,确实printf compare_value[2]是下一个地址中内容。
所以即使我按方法2改了,也是程序中的BUG,不知道会更改哪个变量呢。

使用特权

评论回复
13
john_light| | 2007-12-1 16:59 | 只看该作者

数组越界了

C语言的经典陷阱之一

使用特权

评论回复
14
hotpower| | 2007-12-1 17:02 | 只看该作者

哈哈~~~

使用特权

评论回复
15
yongzai| | 2011-5-4 12:18 | 只看该作者
楼上的各位都是高手啊

使用特权

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

本版积分规则

58

主题

409

帖子

1

粉丝