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

Posted 嵌入式大杂烩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了串口数据传输当中的共用体和结构体转换相关的知识,希望对你有一定的参考价值。

👇 星标「嵌入式大杂烩」,一起进步!👇

推荐文章:STM32如何收发float类型数据?

嵌入式系统的串口数据传输都是以字节为单位,但是有些特殊的数据类型,比如浮点型float a=231.5,在内存是如何表示的呢?

我们知道浮点型float数据类型占用4个字节,实际上在内存当中a=0x43678000,只是嵌入式芯片访问a时,知道a是浮点型数据,所以一次性读取4个字节,而且也按照浮点型的数据表示规定,将a转换为十进制的可读数据231.5。

如果我们从串口接收到4个字节数据0x43,0x67,0x80,0x00,如何把这4个字节的数据转换为float型呢?

直接令float a=0x43678000这是不行的(不信的读者可以自行验证),这就是串口通讯当中经常遇到的问题,如果数据传输中包括了浮点型数据,在这里我们可以通过共用体或者结构体来解决。

对于共用体:

typedef union

  float f;
  unsigned char s[4];
Union_test;

f的4个字节和s[4]的4个字节是共用一个区域,如果我们令f=231.5,然后通过VS的监视窗查看s[4]的数值,下面是测试程序:

#include <stdio.h>
//共用体
//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("大端存储");

原文:https://www.cnblogs.com/codecamel/p/4703174.html

免责声明:本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。

------------ END ------------

往期推荐:

第一个编译器是怎么来的?

一份硬核的QT开发经验及资料分享,长文收藏!

分享一个简洁易用的嵌入式操作系统内核

点击阅读原文,查看更多分享

以上是关于串口数据传输当中的共用体和结构体转换的主要内容,如果未能解决你的问题,请参考以下文章

C语言结构体和共用体_07

结构体共用体和枚举类型

USRP通信的结构体和常量(上位机下位机共用)

C语言中的结构体和共用体(联合体)

C语言 结构体和共用体的初始化

结构体与共用体