2017-06-04 4 views
-1

私は現在USB経由でフロートを送信しようとしています。 PCは、私がこのサイトSTM32がPCからUSBでフロートされ、エンディアンが苦労しています

に応じて、以下の順序

.. 00 00 00 40 .. 

を通過する一連のバイトをはっきりと見ることができるDEBUGLOG機能では、次のコード

float x = 2.0; 
memcpy(buffer.data() + 14, &x, sizeof x); 

を実行しているQtアプリケーションを持っています

http://www.scadacore.com/field-tools/programming-calculators/online-hex-converter/

は、リトルエンディアンの場合には、1073741824に変換されます。

私は私が

をすれば、実際に本物のfloat値に2.0

を変換したいときに問題が発生し、その後LED4

uint32_t a = buffer[14] | (buffer[15] << 8) | (buffer[16] << 16) | (buffer[17] << 24);      
if (a == 1073741824){ 
    HAL_GPIO_WritePin(LED4_PORT, LED4_PIN, GPIO_PIN_RESET); 
} 

を回すために、次のコードを使用することができます私のSTM32の

float b = buffer[14] | (buffer[15] << 8) | (buffer[16] << 16) | (buffer[17] << 24); 
if (b == 2.0f){ 
    HAL_GPIO_WritePin(LED5_PORT, LED5_PIN, GPIO_PIN_RESET); 
} 

LED5が点灯していません。

エンディアンの問題ですか? float値2.0を取得するにはどうすればよいですか?

よろしく、IEEE 754浮動小数点数については

+1

フロートをASCIIテキストとして送信し、もう一方の端に戻します。それだけで安全で簡単です。 – ThingyWotsit

+0

"2.0"(CRまたはNULと言う)は、両者がプロトコルを知っている限り、単一のものと同じサイズであり、誤解が容易ではありません。また、終端文字を持つプロトコルは、rx呼び出しが完全なメッセージ/ floatのために必要とされるよりも少ないバイトで「早い」ものを返すストリーミング接続の問題を回避します。 – ThingyWotsit

+0

例を挙げることができますか? – Luigi

答えて

1

、エンディアンは通常ない問題ですが、念のために確認してください。

あなたの主な問題は値を読み取ることです。あなたは整数算術でORing値を返し、整数値を取得しますが、それは正しいですが、をfloatに変換します。これは常にゼロ以外のゴミを与えます。

あなたはフロートとして再解釈する必要があります。あなたは使用することができます。

  • ポインタキャスト:float a = *(float*)&myInt;
  • memcpymemcpy(&myFloat, &myInt, 4);
  • 組合:union { uint32_t i; float f; };u.i = myInt; float f = u.f;

をあなたはまた、浮動小数点を比較する際に注意する必要があります。 2.0fは近似値であるため、一般にはif(f == 2.0f)と書くことは悪い考えです。 ==を避けて、代わりに> >= < <=を使用する方がよいでしょう。範囲ではなく特定の値をチェックする場合は、精度のニーズに合った範囲で、値の周りの小さな範囲を確認します。

+0

私はそれを試して報告して戻します。とにかく私は、与えられたuint32は固定されたfloatにしか変換できないと思った。そうじゃない? – Luigi

+0

@Luigiはい、すべてのuint32は有効で異なるフロートを表すことができます。しかし、変換することで、浮動小数点数の範囲のほんの一部を得ることができます。たとえば、 '1.0f'は' 0x3F800000'で表されます。** ** **変換すれば '1.0'を返さない整数です。 – ElderBug

+0

配列の要素だけで/直接作業するためのショートカットはありますか? – Luigi