您现在的位置是:亿华云 > 应用开发
联合体在单片机编程中的应用
亿华云2025-10-09 13:46:39【应用开发】5人已围观
简介01联合体之前的文章《枚举和结构体的结合》文中提到,结构体就像是打包封装,把一些有共同特征的变量封装在内部。结构体是一种构造类型或复杂类型,它可以包含多个类型不同的成员。在C语言中,还有另外一种和结构
01联合体
之前的联合文章《枚举和结构体的结合》文中提到,结构体就像是体单打包封装,把一些有共同特征的片机变量封装在内部。结构体是编程一种构造类型或复杂类型,它可以包含多个类型不同的应用成员。在C语言中,联合还有另外一种和结构体非常类似的体单语法,叫做联合体(Union)(有些地方也叫做共用体)。片机
联合体举例如下
union data{
char n;
char ch;
char f;
};
union data a,编程 b, c;结构体和联合体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而联合体的应用所有成员占用同一段内存,修改一个成员会影响其余所有成员。联合
结构体占用的体单内存大于等于所有成员占用的内存的总和(存在字节对齐问题,这里不深入讨论)。片机
联合体占用的编程内存等于最长的成员占用的内存。联合体中如果对新的应用成员赋值,就会把原来成员的高防服务器值覆盖掉。
//上文的联合体定义
char data;
a.n = 0x0A;//虽然只修改了成员变量n,但是ch和f变量都会被改变
data = a.f;//那么data的值就会被修改为0x0A02联合体的应用
联合体在一般中的编程应用中还是很少的,在单片机编程中较多,在之前的文章《枚举和结构体的结合》将枚举和结构体的结合,下面的例子简单说明下联合体在结构体中的应用(我的日常开发中联合体一般都是和结构体一起使用的)。
在做显示屏应用时牵扯到一个概念,显示屏(全彩)上一个像素点是由于Red,Green,Blue三种颜色组成,在888模式下,每个像素点都是由8个bit组成的,这个时候为了便是一个像素点就需要用到结构体,这也对应前面的b2b信息网文章,结构体就像是打包封装,把一些有共同特征的变量封装在内部。
typedef struct{
uint8_t Red;
uint8_t Green;
uint8_t Blue;
uint32_t Pix_Value;
}LCD_Pixvalue_S;上面这样的写法是十分清晰的,访问很方便,可以单独访整个像素,也可以访问像素的某个颜色,有个问题那就是我操作红色像素,需要重新给Pix_Value成员赋值,如下
LCD_Pixvalue_S LCD_Pixvalue;
LCD_Pixvalue.Red = 0x12;
LCD_Pixvalue.Pix_Value = LCD_Pixvalue.Red<<16 | LCD_Pixvalue.Red<<8 |LCD_Pixvalue.Blue;需要多一句代码,并且内存占用也大。当然,直接用下面写法,不会多占用内存,但是访问不方便。
typedef struct{
uint32_t Pix_Value;
}LCD_Pixvalue_S;那么这个时候,使用联合体和结构体组合起来,就可以既不会多占内存,访问也很方便。
typedef union{
struct{
uint8_t Red;
uint8_t Green;
uint8_t Blue;
}Pix;
uint32_t Pix_Value;
}LCD_Pixvalue_S;那么就可以如下操作
LCD_Pixvalue_S LCD_Pixvalue;
uint32_t data;
LCD_Pixvalue.Pix_Value = 0x0012FF00;
LCD_Pixvalue.Pix.Red = 0x25;//单独修改红色
data = LCD_Pixvalue.Pix_Value;//data的值就为0x0025FF00当然,结构体的定义你也可以写到外面,其他地方可以使用,如下
typedef struct{
uint8_t Red;
uint8_t Green;
uint8_t Blue;
}Pix_s;
typedef union{
Pix_s Pix;
uint32_t Pix_Value;
}LCD_Pixvalue_S;那么关于内存占用的站群服务器问题,上面的定义方法,定义一个LCD_Pixvalue_S类型的变量占用4个字节。示例图如下
03联合体在串口开发中的应用
上面举例LCD应用中联合体的应用,这个是由于LCD一个像素由红绿蓝3色组成,所以用联合体很方便。在单片机项目开发中,串口协议解析也可以利用到联合体,十分方便。
在私有自定义协议中,合理定义协议,利用联合体代码十分方便。下面的例子不讲帧头,帧尾部分,举例联合体在协议解析中的应用,灵活应用。
串口协议举例如下
功能
字节长度
命令长度
4
命令字
1
命令内容
7
crc16
2
那么代码可以如下编写
typedef union{
struct{
uint32_t cmdlen;
uint8_t cmd;
uint8_t cmdbuf[7];
uint16_t crc16;
}unit;
uint8_t buffer[14];
}uart_buffer_s;
uart_buffer_s uart_buffer;
int main(void)
{
uint8_t len;
len = 0;
uart_buffer.buffer[len++] = 0x12;
uart_buffer.buffer[len++] = 0x34;
uart_buffer.buffer[len++] = 0x56;
uart_buffer.buffer[len++] = 0x78;
uart_buffer.buffer[len++] = 0xAA;
for(int i=0;i<7;i++)
{
uart_buffer.buffer[len++] = i;
}
uart_buffer.buffer[len++] = 0x11;
uart_buffer.buffer[len++] = 0x22;
while (1);
}运行的结果如下
可以看到,我们只是往uart_buffer.buffer填充数据,模拟串口接收数据,接收完毕后,就自动解析出来我们自定义的cmdlen,cmd,cmdbuf和crc16。这里需要注意的是16位和32位的数据类型是小端模式,关于小端模式请看之前的文章《C语言在STM32中的内存分配》,这个还是很方便的。
!!!但是!!!需要注意字节对齐的问题,比如把上述cmdbuf修改为8个字节,就会出问题,如下
crc16就会出问题,这个就是字节对齐的问题,不懂的同学自行百度一下,这里不再重点讲解。
除了上述自定义协议解析时会用到联合体,还可以解决浮点型float的读取问题,float是占用4个字节的,如果将从串口接收的4个字节转换成float呢?联合体就可以可以解决这个问题
下面示例代码,我们知道浮点数231.5的16进制表示为0x43678000。
typedef union{
float data;
uint8_t buffer[4];
}uart_buffer_s;
uart_buffer_s uart_buffer;
int main(void)
{
uint8_t len;
len = 0;
uart_buffer.buffer[len++] = 0x00;
uart_buffer.buffer[len++] = 0x80;
uart_buffer.buffer[len++] = 0x67;
uart_buffer.buffer[len++] = 0x43;
while (1);
}结果如下
可以看到我们模拟从串口收到4个字节,使用联合体,不用我们额外写代码,就可以自动转化为float型。当然这个转换也是小端模式的,小端模式详解请看文章《C语言在STM32中的内存分配》。
很赞哦!(5)
相关文章
- 四、一定要仔细阅读细节
- 公司名字不但要与其经营理念、活动识别相统一,还要能反映公司理念,服务宗旨、商品形象,从而才能使人看到或听到公司的名称就能产生愉快的联想,对商店产生好感。这样有助于公司树立良好的形象。
- 4、待所有域名查询结束后可在右侧点击导出结果,即可以excel的文件方式将查询到的结果导出。
- 互联网其实拼的也是人脉,域名投资也是一个时效性很强的东西,一个不起眼的消息就会引起整个域名投资市场的动荡,因此拓宽自己的人脉圈,完善自己的信息获取渠道,让自己能够掌握更为多样化的信息,这样才更有助于自己的域名投资。
- 域名和网址一样吗?域名和网址有什么区别?
- 域名不仅仅是一个简单的网站。对于有长远眼光的公司来说,在运营网站之前确定一个优秀的域名对有长远眼光的公司来说是非常重要的。这对今后的市场营销、产品营销和企业品牌建设都具有十分重要的意义。优秀的域名是企业在市场竞争中获得持久优势的利器。
- 3、查看排名
- 在数以亿计的网站中,我们应该抓住每一个可能带来宣传的机会,域名可以带有企业的名字,一般可以使用汉语拼音或者英语单词或者是相关缩写的形式,只要用户记住了你企业的名字,就能很容易的打出你的网站域名,同样的,记住了网站域名也能很快的记住你公司的名字。
- 4、域名传输时,取决于域名原始用户的邮箱是否有效,以及他是否将密码发送到此邮箱。
- 四、一定要仔细阅读细节
热门文章
站长推荐
4、club娱乐
域名资源有限,好域名更是有限,但机会随时都有,这取决于我们能否抓住机会。一般观点认为,国内域名注册太深,建议优先考虑外国注册人。外国注册人相对诚实,但价格差别很大,从几美元到几十美元不等。域名投资者应抓住机遇,尽早注册国外域名。
第五步:重复第四步,直到找到正确的纪录。
其次,一般域名注册有一个获取密码的按钮,域名注册商点击后会向您发送密码。在得到域名注册商发送的密码后,将其传输到域名服务提供商网站,然后输入密码,此时域名呈现申请状态。提交申请后,原注册人通常会向您发送一封电子邮件,询问您是否同意转让。此时,您只需点击同意转移按钮,域名注册商就可以成功转移。
比较短的域名方便用户记忆和传播,它带来的好处往往会超过其他类型的域名,如果你非要域名短而且还要包含关键词,那么往往会事与愿违,现在这种域名基本上是可遇而不可求的。
四、长串数字域名
4、企业无形资产:通用网站已成为企业网络知识产权的重要组成部分,属于企业的无形资产,也有助于提升企业的品牌形象和技术领先形象。它是企业品牌资产不可或缺的一部分。
5、企业注册国内域名需要证件,其它情况一律不需要证件。