我目前正在尝试通过 USB 发送 float 。 PC 有一个运行以下代码的 Qt 应用程序
float x = 2.0;
memcpy(buffer.data() + 14, &x, sizeof x);
通过调试日志功能,我可以清楚地看到按以下顺序传递的一系列字节
.. 00 00 00 40 ..
根据这个网站
http://www.scadacore.com/field-tools/programming-calculators/online-hex-converter/
在小字节序的情况下转换为 1073741824。
在我的 STM32 上,我可以使用以下代码打开 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);
}
当我想转换为真正的float值2.0时出现问题
如果我愿意
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 没有打开。
这是字节序问题吗? 如何获取浮点值 2.0?
问候,
最佳答案
对于 IEEE 754 float ,字节序通常不是问题,但检查一下以确定。
您的主要问题是读取值。您在整数运算中对值进行 ORing 并得到一个整数值,这是正确的,但随后您将其转换为 float 。这将始终给出垃圾,除了 0。
您需要将其重新解释为 float 。您可以使用:
- 指针转换:
float a = *(float*)&myInt;
- A
memcpy
:memcpy(&myFloat, &myInt, 4);
- union :
union { uint32_t i; float f; };
,u.i = myInt; float f = u.f;
比较 float 时也需要小心。编写 if( f == 2.0f )
通常不是一个好主意。 ,因为 2.0f
是一个近似值。最好避免 ==
,并使用 > >= < <=
反而。如果您想检查特定值而不是范围,请检查您的值周围足够小的范围,并且您的范围符合您的精度需求。
关于c++ - STM32 从 PC 通过 USB float ,endianess 挣扎,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44353354/