干货 | union在嵌入式中的一种实用应用

其中应用于管理不同的数据的用法中有一些小伙伴不是很理解,给我留言了。这篇文章我们就一起看一些实例来进一步理解。

温馨提示:本公众号由于开通得比较晚,所以不具备留言功能。所以大家想看哪些内容,可以在公众号聊天界面留言,小编会参考大家的一些意见输出一些小编的能力范围内能写的内容。另外,本人水平有限,文章中如若出现错误或笔误,也可在聊天界面留言告知我,谢谢!一起成长、一起进步。期待留言~

以下面这个例子为例:

我们看一看这个例子中用到哪些数据:

1、7个用电器状态

2、4个电源线参数

在这个例子中,我们该如何创建数据会比较好呢?

方法一:全局变量

方法一就比较简单粗暴了:

/* 公众号:嵌入式大杂烩 */
uint8_t ele1_status;
uint8_t ele2_status;
uint8_t ele3_status;
uint8_t ele4_status;
uint8_t ele5_status;
uint8_t ele6_status;
uint8_t ele7_status;
float voltage;
float current;
float active_power;
float reactive_power;

这种方法是我们刚学编程、单片机的时候经常这么干,包括现在工作了,一些做算法的同事大都是这么干的。这里我们不讨论使用全局变量的好坏。我们从代码的风格上看,这么多数据,就这么摆着,感觉很散乱。

方法二:创建一个结构体

既然这些数据都是要显示到屏幕上的数据,那我们可以用一个结构体包起来:

/* 公众号:嵌入式大杂烩 */

/* lcd显示的数据 */
struct lcd_disp_data
{
 /* 用电器状态 */
 uint8_t ele1_status;
 uint8_t ele2_status;
 uint8_t ele3_status;
 uint8_t ele4_status;
 uint8_t ele5_status;
 uint8_t ele6_status;
 uint8_t ele7_status;
 /* 电源线参数 */
 float voltage;
 float current;
 float active_power;
 float reactive_power;
};

这样看起来较全局变量没那么乱,也更便于管理一些。实际编程中,我们可能会把struct lcd_disp_data当做一个整体(或者叫做对象)来使用,假如操控这样一个整体发送到LCD进行显示,需要发送多少字节数据呢?

我们不考虑字节对齐,至少占用23个字节数据:

假如我们有时候只需要单独更新用电器状态或电源线参数呢,那岂不是白白传输了多余的数据,增加了通信负担。方法三可稍微减轻通信负担,下面看看方法三:

方法三:联合体嵌套结构体

使用联合嵌套结构体的方法可以弥补方法二的缺点,这就是我们文首提到的方法,也是我们本篇笔记想要分享的内容。下面针对这个例子看看具体做法:

/* 公众号:嵌入式大杂烩 */

/* 数据包类型 */
enum DATA_PKG_TYPE
{
    ELE_STATUE_PKG  = 1,
    POWER_LINE_PARA = 2    
};

/* 用电器状态 */
struct ele_status
{
 uint8_t ele1_status;
 uint8_t ele2_status;
 uint8_t ele3_status;
 uint8_t ele4_status;
 uint8_t ele5_status;
 uint8_t ele6_status;
 uint8_t ele7_status;
};

/* 电源线参数 */
struct power_line_para
{
 float voltage;
 float current;
 float active_power;
 float reactive_power;
};

/* lcd显示的数据 */
struct lcd_disp_data
{
 enum DATA_PKG_TYPE data_pkg_type;

union
 {
  struct ele_status ele_status_info; 
  struct power_line_para power_line_para_info; 
 }data_pkg_info;
};

下面看看不考虑对齐的情况,struct lcd_disp_data占多少字节:

可见,能节省了一定的空间,数据包数越多,效果越明显。

这里加了一个data_pkg_type数据包类型,这是必须的,否则接收端并不能识别发送端发送的是什么类型的数据。

发送数据如:

1、发送用电器状态数据

/* 公众号:嵌入式大杂烩 */

/* 发送用电器状态数据 */
tx_data.data_pkg_type = ELE_STATUE_PKG;
tx_data.data_pkg_info.ele_status_info.ele1_status = 1;
tx_data.data_pkg_info.ele_status_info.ele2_status = 1;
tx_data.data_pkg_info.ele_status_info.ele3_status = 1;
tx_data.data_pkg_info.ele_status_info.ele4_status = 1;
tx_data.data_pkg_info.ele_status_info.ele5_status = 1;
tx_data.data_pkg_info.ele_status_info.ele6_status = 1;
tx_data.data_pkg_info.ele_status_info.ele7_status = 1;

2、发送电源线参数数据

/* 公众号:嵌入式大杂烩 */

/* 发送电源线参数数据 */
tx_data.data_pkg_type = POWER_LINE_PARA;
tx_data.data_pkg_info.power_line_para_info.voltage = 220.0;
tx_data.data_pkg_info.power_line_para_info.current = 0.044;
tx_data.data_pkg_info.power_line_para_info.active_power = 4.966;
tx_data.data_pkg_info.power_line_para_info.reactive_power = 0.22;

接收数据如:

/* 公众号:嵌入式大杂烩 */

switch (data_pkg_type)
{
 case ELE_STATUE_PKG : 
 // 解析用电器状态数据......
 break;
 
 case POWER_LINE_PARA : 
 // 解析电源线参数数据......
 break;
 default: break;
}

以上就是本次的分享,如有错误,欢迎指出,谢谢!

如果觉得文章有用,麻烦帮忙转发,有更多的人阅读也是我们继续更新的动力!

(0)

相关推荐

  • C语言之struct A *b和struct A c区别

    struct A *b; 是指针 struct A c; 是定义了一个struct A对象,你得提供相应的结构体的具体定义 结构体A没有具体的定义,当struct A c时,实际是定义一个结构体变量, ...

  • 嵌入式算法8---空间向量夹角公式及其应用

    有些设备正常工作时需按合适的方位安装,比如GPS天线必须朝向天空才能保证信号最佳,温湿度传感器监测口必须朝向被测目标才能及时响应.软件需求是在安装角度异常时提醒用户改变位置.那设备如何感知当前方位呢? ...

  • LTE系统调试记录5:matlab中将一个32位的数据分为4个8位数据,存储到一个数组中

    result = uint32data(4) + bitshift( uint32data(3), 8) + bitshift( uint32data(2), 16) + bitshift( uint ...

  • 使用Python读取二进制文件

    目标:目标文件为一个float32型存储的二进制文件,按列优先方式存储.本文使用Python读取该二进制文件并使用matplotlib.pyplot相关工具画出图像 工具:Python3, matpl ...

  • 美术干货!素描绘画中,几种实用的“线”的运用技巧

    线条在素描绘画中是非常重要的, 尤其对于画画初学者来讲, 线的表现方式灵活多样, 也非常丰富,可长可短.可粗可细. 可曲可直,线是艺术表现的生命力. 还可以用排线的方法来表现一个面 线的轻重变化形成面 ...

  • ​干货:趋势交易中的三种稳健制胜方法

    要想在"没有硝烟"的证券市场 上取得成功,必须拥有一套适合自己的操作系统.俗话说,"条条大路通罗马",采用什么方法并不重要,重要的是通往成功之路的方法必须符合自 ...

  • 干货:趋势交易中的三种稳健制胜方法

    把简单做到了极致,就成了成功者. 所以在我看来:一个成熟的交易员,最终必须回归到最简单.最原始的几项技术.但刚起步的人不可以追求简单,新手一定得经历一个修炼过程,这是成长的基础.就像学武功,基本功和套 ...

  • 替代串口打印,快来围观嵌入式中另一种打印调试的方法

    一.前言 在我们的嵌入式开发中,常常把printf重定向到MCU的串口外设,再配合上位机界面软件,通过打印调试信息的方式来调试我们的嵌入式软件. 此处,我们介绍另一种打印调试的方法--SEGGER 的 ...

  • 书法创作中的7种实用搭配技巧

    岐黄名家经方 1篇原创内容 Official Account 收藏岐黄名家经方学习 111 写字,离不开"组合"这两个字,或者叫"搭配"."配合&qu ...

  • C语言、嵌入式中几个非常实用的宏技巧

    宏打印函数 在我们的嵌入式开发中,使用printf打印一些信息是一种常用的调试手段.但是,在打印的信息量比较多的时候,就比较难知道哪些信息在哪个函数里进行打印. 特别是对于异常情况的打印,我们需要快速 ...

  • 技术干货:嵌入式中参数存储的一种方式

    导读: 如果有几个设置参数需要存储到Flash中,我们一般会怎么存储呢?将不同的参数都存储到不同的页中,还是将这几个参数捆绑成一种结构体,每次修改都同时写入一次呢? 如果有几个设置参数需要存储到Fla ...

  • 南京艺之行画室干货分享!油画创作中常见的几种实用技法

    在美术生涯中,很多画家在创作过程中,结合自身的经验和灵感,突然拼发出对画画运用的技巧.一笔一画,勾勒出不同的天地,而今天南京艺之行画室老师要讲的是,油画创作过程中,常见的几种实用技法?南京艺之行画室的 ...

  • 【干货】对赌协议中常见的18种关键条款

    来源:中华创投家,转载请注明来源. 导读:对赌协议双方中,公司与公司大股东一方处于相对弱势的地位,只能签订「不平等条约」,业绩补偿承诺和上市时间约定是协议中的重要条款,而对赌协议,则是 PE.VC 投 ...