Quel est le problème avec cette arithmétique lors de l'utilisation de SDCC (Little Endian) Compilateur?

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

Question

Je suis très nouveau à la programmation en C et je suis en train de travailler sur un firmware application pour mon MCU.Cette méthode marchait très bien quand j'utilise le compilateur KEIL (Big Endian), mais quand je suis passé au compilateur SDCC (Little Endian) il ne fonctionne pas correctement.Quelqu'un peut-il expliquer ce que je fais de mal???

Le périphérique cible est un Silicon Labs C8051F320 qui est basé sur le 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;
}

AJOUTÉ:Tout d'abord, j'ai changé le MotorSteps et MotorSpeed être unsigned ints. Dans mon débogueur, pour une raison quelconque, si j'ai mis un point d'arrêt au le if de la ligne, sur la première entrée de cette fonction MotorSteps = 00, de sorte que t doit obtenir assignés à 0 aussi mais le débogueur montre que t=0.031497 (décimal).Si je passe le débogueur pour afficher en Hexadécimal, t = 0x3d010300.C'est comme t n'est jamais affecté...

Était-ce utile?

La solution

Si MotorSteps = 49 alors

(50 - 49) / 50 = 0.02

prochaine

(1 - 0.02) = 0.98

et

0.98 * 15 = 14.7

La quadrature cette valeur aurait la valeur de t

t = 14.7 * 14.7 = 216.09

Enfin, la conversion implicite de la flotte de la unsigned char débordements de la MotorSpeed variable:

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

La somme de 100 + 216 = 316, bien sûr, des débordements d'un unsigned char, et vous vous retrouvez avec 316-256 = 60.

C'est probablement un comportement indésirable quel que soit le compilateur.

Autres conseils

C'est comme t est de ne jamais s' affecté...

Il n'y a aucune raison pour que le compilateur pour affecter une valeur de 0 à t dans la déclaration

float t = 0;

depuis, il obtient immédiatement affecté à MotorSteps sur la ligne suivante.Ma conjecture est que l'optimiseur est ignorant la cession à zéro dans la déclaration et le débogueur est tout simplement l'affichage de la valeur non initialisée pour la mémoire où t est situé sur la pile.

Vous pourriez envisager de se débarrasser de la formule tout à fait et à l'aide d'une table pour la rampe des valeurs.Il semble que il ya seulement 51 valeurs de sorte que le tableau serait relativement faible.Le code pour rechercher une valeur serait beaucoup plus rapide que l'utilisation de la virgule flottante bibliothèques sur 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;
}

Au moins vous pouvez tester votre entier plutôt que le flotteur pour éviter la virgule flottante bibliothèques, sauf si vous en avez besoin...

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

pourquoi avez-vous passez d'ÊTRE à CHIER?Qu'est-ce que l'architecture de la cible de l'appareil?Et par la façon dont c'est quoi?

De toute façon, à la question.Je suis assez sûr que le problème vient quand la conversion a lieu.Essayez de retrouver votre code ligne par ligne, avec calculatrice et essayer de trouver quand les numéros de devenir inattendu.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top