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


    嵌入式系统的串口数据传输都是以字节为单位,但是有些特殊的数据类型,比如浮点型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,然后通过VS2008的监视窗查看s[4]的数值,下面是测试程序

     1 #include <stdio.h>
     2 //共用体
     3 //float f;//4个字节
     4 //char s[4];//4个字节
     5 typedef union
     6 {
     7     float f;
     8     unsigned char s[4]; 
     9 }Union_test;
    10 typedef struct st
    11 {
    12     float f1;
    13 }Struct_test;
    14 void main(void)
    15 {
    16     float a=231.5;
    17     Union_test x;
    18     Struct_test z;
    19     x.f = a;
    20     z = *(Struct_test *)(&(x.s));
    21     printf("z=%.2f
    ",(double)z.f1);
    22     printf("End of this programme
    ");
    23 }

    监视结果如下所示

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

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

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

    举个例子,对于十六进制数0x01234567,其字节的存储顺序便依赖于机器,如下
    我们可以通过下面的函数测试是大端存储还是小端存储
    1 void test(void)
    2 {
    3     int a = 1;
    4     unsigned char *start=&a;
    5     if(*start == 1)
    6         printf("小端存储");
    7     else if(*start == 0)
    8         printf("大端存储");
    9 }

     附录:结构体的定义方法

    1.先定义结构,再说明结构变量。 如:

    1 struct stu
    2 {
    3     int num;
    4     char name[20];
    5     int age;
    6 };
    7 struct stu boy1,boy2;

    说明了两个变量boy1和boy2为stu结构类型。

    2.在定义结构类型的同时说明结构变量。例如:

    1 struct stu
    2 {
    3     int num;
    4     char name[20];
    5     int age;
    6 }boy1,boy2;

    3.直接说明结构变量。

    1 struct
    2 {
    3     int num;
    4     char name[20];
    5     int age;
    6 }boy1,boy2;  

    第三种方法与第二种方法的区别在于第三种方法中省去了结构名,而直接给出结构变量。

    说明了boy1,boy2变量为stu类型后,即可向这两个变量中的各个成员赋值。

    参考网址:http://blog.csdn.net/xiaoyali/article/details/4393486

  • 相关阅读:
    PAT1092:To Buy or Not to Buy
    PAT1027:Colors In Mars
    PAT1099:Build A Binary Search Tree
    PAT1064: Compelte Binary Search Tree
    PAT1008:Elevator
    TP5整合 WorkerMan 以及 GatewayWorker
    ThinkPHP5通过composer安装Workerman安装失败问题
    浏览器控制台
    webpack线上和线下模式
    PHP读取文件夹目录,按时间排序,大小排序,名字排序
  • 原文地址:https://www.cnblogs.com/codecamel/p/4703174.html
Copyright © 2020-2023  润新知