I am very new at C programming and I am working on a firmware application for my MCU. This method was working fine when I was using the KEIL compiler (Big Endian) but when I switched to the SDCC compiler (Little Endian) it is not working properly. Can someone please explain what I am doing wrong???
The target device is a Silicon Labs C8051F320 which is based on the 8051 architecture.
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;
}
ADDED: First, I now changed the MotorSteps and MotorSpeed to be unsigned ints. In my debugger, for some reason, 开发者_JAVA百科if I set a break point at the if-statement line, on the first entrance of this function MotorSteps = 00, so t should get assigned to 0 also but the debugger shows that t=0.031497 (decimal). If I switch the debugger to display in Hex, t = 0x3d010300. It's like t is never getting assigned...
If MotorSteps = 49 then
(50 - 49) / 50 = 0.02
next
(1 - 0.02) = 0.98
and
0.98 * 15 = 14.7
Squaring this value would set t as
t = 14.7 * 14.7 = 216.09
Finally, the implicit conversion from the float back to the unsigned char overflows the MotorSpeed variable:
MotorSpeed = 100 + 216.09...// Implicitly converts the float t to an unsigned char of 216
The sum of 100 + 216 = 316, of course, overflows an unsigned char and you end up with 316-256 = 60.
This is probably unwanted behavior regardless of the compiler.
It's like t is never getting assigned...
There is no reason for the compiler to assign a value of 0 to t in the declaration
float t = 0;
since it immediately gets assigned to MotorSteps on the next line. My guess is the optimizer is ignoring the assignment to zero in the declaration and the debugger is simply displaying the uninitialized value for the memory where t is located on the stack.
You might want to consider getting rid of the formula altogether and using a look up table for the ramp values. It looks like there are only 51 values so the table would be relatively small. The code to look up a value would be much quicker than using the floating point libraries on an 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;
}
At least you could test your integer rather than the float to avoid the floating point libraries unless you need them...
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;
}
why did you switch from BE to LE? What is architecture of target device? And by the way what is it?
Anyway, to question. I am pretty sure that problem comes when conversion takes place. Try to trace your code line by line with calculator and try to find when the numbers become unexpected.
精彩评论