查看原文
其他

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

里米君 嵌入式大杂烩 2021-02-27

点击上方「嵌入式大杂烩」,选择「置顶公众号」第一时间查看嵌入式笔记!


之前分享了《干货 | 结构体、联合体嵌套使用的一些实用操作》中已经详细分享了结构体、联合体嵌套使用的一些实用操作。

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

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

以下面这个例子为例:


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

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;
 defaultbreak;
}

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

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

猜你喜欢:

2020年精选原创笔记汇总

干货 | 结构体、联合体嵌套使用的一些实用操作

长文 | STM32中的一些C语言知识点

干货 | 项目乏力?nanopb助你一臂之力

省电子设计竞赛一等奖作品分享(二)

1024G 嵌入式资源大放送!包括但不限于C/C++、单片机、Linux等。在公众号聊天界面回复1024,即可免费获取!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存