打印
[51单片机]

求大牛解答浮点数结构数组乘法有时会溢出

[复制链接]
2213|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
andirong|  楼主 | 2013-11-15 20:15 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
沙发
NE5532| | 2013-11-15 21:05 | 只看该作者
几个数据的类型定义的是什么?Flot?Double?

使用特权

评论回复
板凳
andirong|  楼主 | 2013-11-15 22:19 | 只看该作者
struct datr{
float dt;
float drt
…}datdat
strcut dart datt[8];

使用特权

评论回复
地板
ayb_ice| | 2013-11-16 08:56 | 只看该作者
任何类型都有溢出可能

使用特权

评论回复
5
andirong|  楼主 | 2013-11-16 21:28 | 只看该作者
哇!见到ayb.ice大牛了,请你讲详细点好吗?我又该怎么防止呢?还有,我有个子函数里有用到float v,s; v=(dat[i].t1-dat[i].t2)*s;而且我开了1毫秒的定时中断,反汇编看里面变量好像会进入别的程序里而没有入栈,出来时值就变了。不知怎么解释。

使用特权

评论回复
6
sunhq02| | 2013-11-17 09:42 | 只看该作者
可能是因为浮点乘法不是原子操作, 是可以被打断的
而中断中可能进行了某些会导致浮点运算局部变量变化的操作
从而导致浮点运算出错

比较粗暴的做法是, 在进行浮点运算前关中断, 运算完后开中断
比较仔细的做法是, 详细分析浮点运算占用了哪些内存, 避开这些内存或者对这些内存进行保护

使用特权

评论回复
7
NE5532| | 2013-11-17 15:31 | 只看该作者
如果确定输入没有导致溢出的可能性,就要找一下楼上说的情况。但是要注意,虽然不是原子操作,但是中断服务程序是会现场保护的,不会影响正常操作。除非是你有内存侵略,或者在中断内外操作了同样的资源。

使用特权

评论回复
8
andirong|  楼主 | 2013-11-18 08:41 | 只看该作者
谢谢斑竹和sunhq02 的解答。我中断计时要求是要准的,所以不能关中断,请问在C中如何实现避开内存呢?

使用特权

评论回复
9
ayb_ice| | 2013-11-18 09:56 | 只看该作者
KEIL C51的浮点操作早就可重入了,

使用特权

评论回复
10
andirong|  楼主 | 2013-11-18 10:52 | 只看该作者
我现在是改浮点数为long型整数运算,但还发现问题,有时程序跑到运算的那个函数里时程序会跑到地址0000h处,在跑就会跑到 这么大的地址,再看函数里的变量时就变了。
   可能我以前判断不对,真正的原因是程序跑飞了,但是怎么会跑飞呢?又该如何处理呢?

使用特权

评论回复
11
ayb_ice| | 2013-11-18 11:08 | 只看该作者
程序都飞了,
狗咬人?
指针乱指?
while(1)?

使用特权

评论回复
12
andirong|  楼主 | 2013-11-18 12:46 | 只看该作者
怎么越调越乱套了,这个时候n的值时2,也就是vol_data[2这个数组,但里面的last_time明显小于count_time,怎么还会跑进if里面了呢?

使用特权

评论回复
13
andirong|  楼主 | 2013-11-18 15:43 | 只看该作者
我是用威福E6000仿真的,没开看门狗;不是是不是仿真器有问题?真是越来越没头绪了。:Q

使用特权

评论回复
14
NE5532| | 2013-11-18 21:21 | 只看该作者
仿真器经常出问题的,以实际运行结果为准。

使用特权

评论回复
15
andirong|  楼主 | 2013-11-19 11:42 | 只看该作者
请斑竹再帮我看看,这是M51文件的堆栈配置
                 0020H.1   0000H.7                *** GAP ***
            DATA    0021H     0022H     UNIT         _DATA_GROUP_
            IDATA   0043H     0001H     UNIT         ?STACK

            * * * * * * *  X D A T A   M E M O R Y  * * * * * * *
            XDATA   0000H     0074H     UNIT         ?XD?MAIN
            XDATA   0074H     002FH     UNIT         _XDATA_GROUP_
我 的堆栈是256-43H的吧?
还有:同样的赋值语句:      n=chan;
      v2temp=0;
      sum=0;
      vau1=vol_data[n].last_time;
      vau2=vol_data[n].count_time;
翻译出的汇编却不一样,到vau2时就会改变chan的值(这是在主程序里1~4循环的)第一条赋值的汇编没有使用R7(chan是存在R7里)二第一条赋值语句最后有这几句:INC DPTR     MOVX A,2dptr     mov r7,a     mov r7,a    把r7更改了,请问这是什么原因?我该如何处理呢?

使用特权

评论回复
16
sunhq02| | 2013-11-21 18:48 | 只看该作者
没有完整的程序,我只能猜一下
函数的局部变量chan放在了通用寄存器中
而数组取元素运算和结构体成员运算都不是原子操作
特别是没有指明存取区域的数组操作实际上是个函数操作
因此会使用通用寄存器
最简单的做法是使用using为中断指明一个不同的通用寄存器组

使用特权

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

本版积分规则

85

主题

121

帖子

0

粉丝