Cosa c'è di sbagliato con questo aritmetica quando si utilizza SDCC (Little Endian) Compilatore?

StackOverflow https://stackoverflow.com/questions/2374367

Domanda

Io sono molto nuovo alla programmazione in linguaggio C e sto lavorando su un firmware di applicazioni per il mio MCU.Questo metodo funziona bene quando stavo usando il KEIL compilatore (Big Endian), ma quando sono passato al compilatore SDCC (Little Endian) non funziona correttamente.Per favore qualcuno può spiegare che cosa sto facendo di sbagliato???

Il dispositivo di destinazione è un Silicon Labs C8051F320 che si basa su l'architettura dell ' 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;
}

AGGIUNTO il:Prima, ora ho cambiato il MotorSteps e velocità motore per essere unsigned int. Nel mio debugger, per qualche motivo, se posso impostare un punto di interruzione in se-economico, il primo ingresso di questa funzione MotorSteps = 00, per cui dovrebbe essere assegnato a 0, ma anche il debugger mostra che t=0.031497 (decimale).Se devo passare il debugger per visualizzare in Hex, t = 0x3d010300.E ' come t è mai sempre ricevuto...

È stato utile?

Soluzione

Se MotorSteps = 49 allora

(50 - 49) / 50 = 0.02

accanto

(1 - 0.02) = 0.98

e

0.98 * 15 = 14.7

La quadratura di questo, il valore di set t come

t = 14.7 * 14.7 = 216.09

Infine, la conversione implicita da galleggiante indietro per il unsigned char supera la velocità motore variabile:

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

La somma di 100 + 216 = 316, naturalmente, l'overflow di un unsigned char e si finisce con 316-256 = 60.

Questo è probabilmente il comportamento indesiderato indipendentemente dal compilatore.

Altri suggerimenti

E ' come t è mai raggiungere ricevuto...

Non c'è nessun motivo per il compilatore assegna un valore di 0 per t nella dichiarazione

float t = 0;

dato che immediatamente viene assegnato MotorSteps sulla riga successiva.La mia ipotesi è che l'ottimizzatore è ignorando l'assegnazione a zero nella dichiarazione e il debugger è semplicemente la visualizzazione di non inizializzati valore per la memoria dove t è situato in pila.

Si potrebbe desiderare di prendere in considerazione sbarazzarsi di la formula del tutto e l'utilizzo di una tabella per la rampa di valori.Sembra che ci sono solo 51 valori in modo che la tabella sarebbe relativamente piccolo.Il codice per la ricerca di un valore molto più veloce rispetto all'utilizzo di una libreria in virgola mobile su 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;
}

Almeno si potrebbe verificare il numero intero, piuttosto che il galleggiante per evitare la libreria in virgola mobile a meno che non hai bisogno di loro...

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

perché si passa da ESSERE per LE?Che cos'è l'architettura del dispositivo di destinazione?E dal modo in cui che cosa è?

Comunque, per la domanda.Io sono abbastanza sicuro che il problema si presenta quando la conversione ha luogo.Cercare di rintracciare il codice riga per riga con il calcolatore e cercare di trovare quando i numeri diventano inaspettato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top