我正在调试缓冲区中出现的数据错误值的问题。我将缓冲区(u8
)类型从内核驱动程序发送到HAL。在HAL中有一个Uint16
缓冲区,它接收来自此缓冲区的值。
//Code to copy BUFFLEN contents from u8 data[BUFFLEN] into uint16_tData ;
uint16_t uint16_tData[BUFFLEN / 2];
float floatdata[BUFFLEN / 2];
我使用此类型转换从uint16_tData
缓冲区获取浮点值:
floatdata[index] = (*((float *)((void *)&uint16_tData[index1];
现在我的问题:如何解释驻留在floatdata
数组中的数据?
假设我有数据floatdata[0] = 53640;
如何在floatdata[0]
注意来自u8的4个字节 - >数组的2个元素uint16_tData - >数组floatdata的一个元素。
我想知道一个例子:
从驱动程序传输的值是:
u8 val1 = 206
u8 val2 = 208
u8 val3 = 120
u8 val4 = 68
在HAL中,转换将如何发生以及我将获得什么价值?
uint16_tData[0] = ?
uint16_tData[1] = ?
如何将数据解释为floatdata
中的浮点数?
floatdata[0] = ?
答案 0 :(得分:1)
为什么这样呢?
我想你想要这个:
float *floatdata;
floatdata = (float *)uint16_tData;
// Now use floatdata[index] ...
一次铸造一件物品是愚蠢的。从uint16_t到float的转换甚至更愚蠢,最好将它保持为uint8_t(字节),这似乎是它的内容,或者至少使用uint32_t作为中间体。
有没有什么可以阻止你这样做?您能想到如何重新设计代码以避免完全处理这些问题吗?
答案 1 :(得分:1)
根据我对你的问题的理解,这就是你想要的
float f ;
uint8_t u8arr[4]={206,208,120,68};
uint16_t arr[2];
memcpy(&arr[0],u8arr,2);
memcpy(&arr[1],u8arr+2,2);
memcpy(&f,arr,4);
答案 2 :(得分:1)
uint16
由“u8
”组成,单精度float
为32位(4 u8或2 uint16),但它们如何“转换”取决于处理这些数据的代码,特别是“发送”的含义(来自内核驱动程序)以及“接收”的代码如何期望数据。我承认我对这个主题一无所知,我现在无法检查和研究它,但我怀疑你有 endianness 的问题:你的数据完全具有“含义”,而不是单个八位字节,但是你把它们以错误的顺序存放在内存中。
基本上,你有一个包含你的octect的缓冲区,比如说
A B C D
u8 u8 u8 u8 4 u8 arr element (arr[0], arr[1] ...)
\____/ \____/
uint16 uint16 2 uint16 arr element (arr[0] and arr[1])
按此顺序增加内存地址。如果您希望A B
被读作“正确的”uint16号码,则必须在内存中“排序”它以便匹配处理器的字节序:例如如果你想在一个小端cpu上使用数字A*8 + B
,你必须以相反的顺序在内存中写两个u8:
B A D C
我怀疑HAL仅使用uint16来存储数据,而不是将它们解释为16位数,因此这里的字节顺序不是问题。但是,一旦你想在内存中从4 u8(或2 uint16)获得正确的“浮动”:你必须按正确的顺序放置u8。
如果你想让你的u8被解释为通过演员表浮动,你首先必须在一个小端机器中以相反的顺序放置它们,例如。
address of arr8[0] and arr16[0]
/
D C B A
u8 u8 u8 u8 4 u8 arr element (arr8[0], arr8[1] ...)
\____/ \____/
uint16 uint16 2 uint16 arr element (arr16[0] and arr16[1])
然后,如果你“读取”这些八位字节在一个litte endian机器上漂浮,你就有了正确的“浮动”。
因此,你应该正确排序你的u8,因为他们知道它们会被解释为宽度超过一个八位字节的另一种类型。对于具有不同字节序的处理器,可移植代码应使用正确的方法进行正确编译。
答案 3 :(得分:0)
我不是HAL / DX友好所以它可能是一个愚蠢的注意事项 但你确定你的花车是16位而不是32位吗?
如果是,请继续阅读
好的,现在你的问题是什么:
你有uint缓冲区,但是将float存储在里面吗?
在这种情况下只需这样做:
float16 *p=(float16*)uint16_tData;
你有uint缓冲区,其中存储了uint值吗?
您有浮动值,需要将它们存储在uint中作为uint
PS。注意某些平台/编译器/数据类型的位移也可以从进位或数字的另一侧插入。在那种情况下,结果使用位掩码。
PPS。不要忘记应用指数偏见!!!
希望它有所帮助