在嵌入式系统中,串口数据传输通常以字节为单位进行。但是对于一些特殊的数据类型,比如浮点型,如何在内存中表示呢?以浮点型变量float a=231.5为例。
我们知道浮点型float数据类型占用4个字节。实际上,在内存中a的表示为0x43678000。然而,嵌入式芯片在访问a时会知道a是一个浮点型数据,因此会一次性读取4个字节,并按照浮点型的表示规定将a转换为十进制的可读数据231.5。
那么,如果我们通过串口接收到4个字节的数据{0x43, 0x67, 0x80, 0x00},如何将这4个字节的数据转换为float类型呢?
直接将float a设置为0x43678000是行不通的(读者可以自行验证)。这是在串口通信中经常遇到的问题。为了解决这个问题,我们可以使用共用体或者结构体。
共用体(union)是一种特殊的数据类型,它允许在相同的内存位置存储不同的数据类型。通过定义一个浮点型共用体,可以将接收到的4个字节数据解释为一个浮点型变量。具体做法是将接收到的4个字节依次存放在共用体的对应位置,并通过共用体访问得到浮点型数据。
结构体(struct)也可以用于将4个字节数据转换为浮点型。通过定义一个只包含一个成员的结构体,并将接收到的4个字节作为该成员的值,然后通过结构体访问得到浮点型数据。
以上,通过使用共用体或者结构体,我们可以将接收到的4个字节数据转换为float类型,解决串口通信中遇到的浮点型数据传输问题。
对于共用体:
typedef union
{
float f;
unsigned char s[4];
}Union_test;
f的4个字节和s[4]的4个字节是共用一个区域,如果我们令f=231.5,然后通过VS的监视窗查看s[4]的数值,下面是测试程序:
#include
//共用体
//float f;//4个字节
//char s[4];//4个字节
typedef union
{
float f;
unsigned char s[4];
}Union_test;
typedef struct st
{
float f1;
}Struct_test;
void main(void)
{
float a=231.5;
Union_test x;
Struct_test z;
x.f = a;
z = *(Struct_test *)(&(x.s));
printf("z=%.2f\r\n",(double)z.f1);
printf("End of this programme\r\n");
}
监视结果如下所示:
我们同样适用结构体做了相同的实验,将数组s[4]={0x00,0x80,0x67,0x43}的首地址s[0]强制转换赋值给结构体z,最后打印输出的结果也是231.5
这里我们看到原本应该是0x4367_8000的数据实际存储的时候变成了00H 80H 67H 43H,这是因为计算机系统使用了小端存储,什么是小端存储呢?
我们都知道,对于一个超过一个字节的数据,其在计算机中的存储需要跨越字节。某些机器选择在存储器中按照从最低为有效字节到最高有效字节的顺序存储对象,而另一些机器则按照从最高为有效字节到到最低为有效字节的顺序存储,前一种存储方式被称为小端存储,后一种方式被称为大端存储。
举个例子,对于十六进制数0x01234567,其字节的存储顺序便依赖于机器,如下:
我们可以通过下面的函数测试是大端存储还是小端存储:
void test(void)
{
int a = 1;
unsigned char *start=&a;
if(*start == 1)
printf("小端存储");
else if(*start == 0)
printf("大端存储");
}
以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !