0

私は C プログラミングが初めてで、MCU のファームウェア アプリケーションに取り組んでいます。この方法は、KEIL コンパイラ (ビッグ エンディアン) を使用していたときは正常に機能していましたが、SDCC コンパイラ (リトル エンディアン) に切り替えたときに正しく機能しません。誰かが私が間違っていることを説明できますか???

ターゲット デバイスは、8051 アーキテクチャに基づく Silicon Labs C8051F320 です。

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 をunsigned int に変更しました。 私のデバッガーでは、何らかの理由で、この関数 MotorSteps = 00 の最初の入り口で、if ステートメント行にブレークポイントを設定すると、t も 0 に割り当てられるはずですが、デバッガーは t=0.031497 (10 進数) を示します。 )。デバッガーを 16 進数で表示するように切り替えると、t = 0x3d010300 になります。t が割り当てられないようです...

4

3 に答える 3

3

MotorSteps = 49 の場合

(50 - 49) / 50 = 0.02

(1 - 0.02) = 0.98

0.98 * 15 = 14.7

この値を 2 乗すると、t は次のように設定されます。

t = 14.7 * 14.7 = 216.09

最後に、float から unsigned char への暗黙的な変換により、MotorSpeed 変数がオーバーフローします。

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

もちろん、100 + 216 = 316 の合計は unsigned char をオーバーフローし、316-256 = 60 になります。

これは、コンパイラに関係なく、おそらく望ましくない動作です。

于 2010-03-03T20:06:45.603 に答える
2

t が割り当てられないようです...

コンパイラが宣言で t に 0 の値を代入する理由はありません。

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;
}
于 2010-03-03T22:42:37.770 に答える
0

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.

于 2010-03-03T19:51:39.940 に答える