什么是错的这个算法使用SDCC(小端)编译器时?
-
24-09-2019 - |
题
我在C编程很新,我正在为我的MCU固件应用。这种方法工作正常,当我使用Keil编译器(大端),但是当我切换到SDCC编译器(小端)就不能正常工作。可有人请解释什么,我做错了???
在目标设备是一个Silicon Labs的C8051F320,其是基于8051体系结构。
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被越来越从未分配...
解决方案
如果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。
这可能是不想要的行为而不管编译器。
其他提示
这就像t被永远不会让 分配...
没有理由为编译器在声明的值0分配至t
float t = 0;
,因为它立即被分配给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;
}
为什么你从BE切换到LE?什么是目标设备的架构?并又是什么呢?
总之,要问题。我敢肯定的是,当发生转换问题就来了。尝试通过在线计算器来跟踪你的代码行,并试图找到当数字成为意外。