Pregunta

Soy muy nuevo en programación en C y estoy trabajando en un firmware de aplicación para mi MCU.Este método estaba funcionando bien, cuando yo estaba usando el compilador KEIL (Big Endian), pero cuando me cambié a la SDCC (Little Endian) no está funcionando correctamente.Por favor alguien puede explicar lo que estoy haciendo mal???

El dispositivo de destino es un Silicon Labs C8051F320 que se basa en la arquitectura 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;
}

AÑADIÓ:En primer lugar, me ha cambiado la MotorSteps y MotorSpeed a ser unsigned int. En mi depurador, por alguna razón, si he de poner un punto de ruptura en el si-línea de sentencia, en la primera entrada de esta función MotorSteps = 00, por lo que t debe asignársele a 0, pero también el depurador muestra que t=0.031497 (decimal).Si me cambio el depurador para mostrar en Hexadecimal, t = 0x3d010300.Es como t es nunca llegar asignado...

¿Fue útil?

Solución

Si MotorSteps = 49 entonces

(50 - 49) / 50 = 0.02

siguiente

(1 - 0.02) = 0.98

y

0.98 * 15 = 14.7

El cuadrado de este valor se establece como t

t = 14.7 * 14.7 = 216.09

Por último, la conversión implícita de que el flotador de vuelta a la unsigned char desborda el MotorSpeed variable:

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

La suma de 100 + 216 = 316, por supuesto, se desborda a un unsigned char, y usted termina con 316-256 = 60.

Esta es, probablemente, el comportamiento no deseado, independientemente del compilador.

Otros consejos

Es como t es nunca llegar asignado...

No hay ninguna razón para que el compilador asigna un valor de 0 para t en la declaración

float t = 0;

ya que de inmediato se le asigna MotorSteps en la línea siguiente.Mi conjetura es que el optimizador está haciendo caso omiso de la asignación a cero en la declaración y el depurador es simplemente mostrar el valor no inicializado para la memoria, donde t se encuentra en la pila.

Puede que desee considerar la posibilidad de deshacerse de la fórmula por completo y el uso de una tabla de consulta para la rampa de valores.Parece que hay sólo 51 de los valores de la tabla sería relativamente pequeño.El código para buscar un valor sería mucho más rápido que usando el punto flotante de las bibliotecas en un 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;
}

Al menos se podía probar su entero más que el flotador para evitar el punto flotante de bibliotecas, a menos que usted los necesita...

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;
}

¿por qué pasar de SER LE?¿Qué es la arquitectura de dispositivo de destino?Y por cierto ¿qué es?

De todos modos, a la pregunta.Estoy bastante seguro de que el problema se presenta cuando la conversión se lleva a cabo.Trate de localizar su código línea por línea con la calculadora y tratar de encontrar cuando las cifras se vuelven inesperado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top