良许Linux教程网 干货合集 串口数据传输当中的共用体和结构体转换

串口数据传输当中的共用体和结构体转换

嵌入式系统中,串口数据传输通常以字节为单位进行。然而,对于特定的数据类型,比如浮点型(float),其在内存中是如何表示的呢?

浮点型数据类型一般占据4个字节的内存空间。以float变量a=231.5为例,在内存中的表示为0x43678000。嵌入式芯片在访问a时,了解a是一个浮点型数据,因此会一次性读取4个字节,并按照浮点型数据的表示规则将其转换为可读的十进制数据231.5。

那么,如果我们通过串口接收到了4个字节的数据{0x43,0x67,0x80,0x00},如何将这些字节数据转换为float型呢?

直接将这4个字节数据拼接成0x43678000赋给float变量a是行不通的(读者可以自行验证)。这是串口通讯中经常遇到的问题之一。为了解决这个问题,我们可以借助共用体或者结构体的方式来进行转换。

对于共用体:

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");
}

监视结果如下所示:

image-20240328225210832
image-20240328225210832

我们同样适用结构体做了相同的实验,将数组s[4]={0x00,0x80,0x67,0x43}的首地址s[0]强制转换赋值给结构体z,最后打印输出的结果也是231.5

这里我们看到原本应该是0x4367_8000的数据实际存储的时候变成了00H 80H 67H 43H,这是因为计算机系统使用了小端存储,什么是小端存储呢?

我们都知道,对于一个超过一个字节的数据,其在计算机中的存储需要跨越字节。某些机器选择在存储器中按照从最低为有效字节到最高有效字节的顺序存储对象,而另一些机器则按照从最高为有效字节到到最低为有效字节的顺序存储,前一种存储方式被称为小端存储,后一种方式被称为大端存储。

举个例子,对于十六进制数0x01234567,其字节的存储顺序便依赖于机器,如下:

image-20240328225213695
image-20240328225213695

我们可以通过下面的函数测试是大端存储还是小端存储:

void test(void)
{
    int a = 1;
    unsigned char *start=&a;
    if(*start == 1)
        printf("小端存储");
    else if(*start == 0)
        printf("大端存储");
}

关于大小端,可以参看我之前分享的文章:

CPU大小端之分

大小端由CPU决定,还是编译器或操作系统决定?

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部