2010-03-03 51 views
0

我在C编程方面很新颖,我正在为我的MCU开发固件应用程序。当我使用KEIL编译器(Big Endian)时,此方法工作正常,但当我切换到SDCC编译器(Little Endian)时,它无法正常工作。有人可以请解释我在做什么错?使用SDCC(Little Endian)编译器时,这种算法有什么问题?

目标器件是基于8051架构的Silicon Labs C8051F320。

unsigned **int** MotorSteps = 0;  //"Global" variables 
unsigned **int** MotorSpeed = 0; 
bit RampUp() 
{ 
    float t = 0; 
    t = MotorSteps; 
    if (t < 51) 
    { 
     t = (1-((50 - t)/50))*15; 
     t = (t * t);   
     MotorSpeed = 100 + t;   
     return 0; 
    } 
    else return 1; 
} 

新增: 首先,我现在改变了MotorSteps和MotorSpeed是无符号整数。 在我的调试器中,出于某种原因,如果我在if语句行中设置了一个断点,则此函数的第一个入口MotorSteps = 00,所以t也应该赋值为0,但调试器显示t = 0.031497 (十进制)。如果我将调试器切换为以十六进制显示,t = 0x3d010300。这就像t永远不会被分配...

+1

这将有助于知道什么MotorSteps和SetSpeedHz看起来像。 – 2010-03-03 19:41:35

+0

这也有助于查看MotorSpeed的声明。 – semaj 2010-03-03 19:46:49

+3

代码中没有任何东西依赖于endian。那么,问题是什么? – AnT 2010-03-03 19:50:25

回答

3

如果MotorSteps = 49然后

(50 - 49)/50 = 0.02 

(1 - 0.02) = 0.98 

0.98 * 15 = 14.7 

磨边这个值将设定T作为

t = 14.7 * 14.7 = 216.09 

最后,从浮子回到无符号字符的隐式转换溢出MotorSpeed变量:

MotorSpeed = 100 + 216.09...// Implicitly converts the float t to an unsigned char of 216 

的100 + 216 = 316的总和,当然,溢出的无符号的字符和你最终316- 256 = 60.

无论编译器如何,这可能是不受欢迎的行为。

+3

实际上,当float的值在整型类型的范围之外时,将浮点(或double)分配给整数类型会导致未定义的行为,但您可能会从无符号整型数中得到良好定义的模块溢出。所以结果可能不是60,这可能解释了为什么这在不同的编译器中表现不同。 – 2010-03-03 20:31:06

0

你为什么从BE切换到LE?目标设备的架构是什么?顺便说一句,它是什么?

无论如何,要质疑。我很确定转换发生时会出现问题。尝试使用计算器逐行跟踪代码,并尝试查找数字何时出现意外。

+2

我最初使用的是KEIL编译器,但是我达到了免费版本的限制,并且不想为许可证支付费用,所以我切换到了SDCC,这是免费且无限制的......但相反的是Endian-ness。 – PICyourBrain 2010-03-04 13:33:07

2

这就像t被越来越从未分配 ...

没有理由对编译器的0值在声明

float t = 0; 

,因为其分配至t立即被分配到下一行的MotorSteps。我的猜测是优化器在声明中忽略赋值为零,而调试器仅显示t位于堆栈上的内存的未初始化值。

您可能需要考虑完全摆脱该公式,并使用查找表来查找斜坡值。它看起来只有51个值,所以表格会相对较小。查找一个值的代码会比使用上的8051

#define NUM_RAMP_STEPS 51 
unsigned char MotorSteps = 0;  //"Global" variables 
unsigned char MotorSpeed = 0; 
const unsigned char RampTable[NUM_RAMP_STEPS] = {...appropriate values...}; 
bit RampUp() 
{ 
    if (MotorSteps < NUM_RAMP_STEPS) 
    { 
     MotorSpeed = RampTable[MotorSteps];   
     return 0; 
    } 
    else return 1; 
} 

浮点库至少你可以测试你的整数,而不是浮动,以避免浮点库,除非你需要更快他们...

unsigned **int** MotorSteps = 0;  //"Global" variables 
unsigned **int** MotorSpeed = 0; 
bit RampUp() 
{ 
    if (MotorSteps < 51) 
    { 
     float t = MotorSteps; 
     t = (1-((50 - t)/50))*15; 
     t = (t * t);   
     MotorSpeed = 100 + t;   
     return 0; 
    } 
    else return 1; 
}