共用体实现浮点数、负数的存储

一、共用体

共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。

定义格式为:

union 共用体名 
{
    共用体成员 1,
    共用体成员 2,
    ...
};

 结构体和共用体的区别:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。

结构体占用的内存大于等于所有成员占用的内存的总和(对齐造成的),共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。

使用场景:

1.通信中的数据包会用到共用体,因为不知道对方会发送什么样的数据包过来,定义几种格式的包,收到包之后就可以根据包的格式取出数据。

2.节约内存。如果有2个大内存的数据结构,但不会同时使用,可以考虑用共用体来设计。

3.某些应用需要大量的临时变量,变量类型不同,而且会随时更换。而堆栈空间有限,不能同时分配大量临时变量。这时可以使用共用体让这些变量共享同一个内存空间,这些临时变量不用长期保存,用完即丢,和寄存器差不多,不用维护。

二、数据存储

 1.浮点数

定义共用体

union eeprom_float
{
	float a;
	uint8_t b[4];
}float_write,float_read;

// 声明
float_write.a = 3.1415926;

浮点数是4个字节,声明float_write.a=3.1415926,由于共用体共占一段内存,把一个float拆分为4个字节,然后逐字节的写入EEPROM,来达到保存float数据的目的。所以,通过float_read.b即可拆分flaot数据

读写数据:

for(i=0;i<sizeof(float);i++)
{
	Write_AT24c02(0+i,float_write.b[i]);
	HAL_Delay(5);
}

for(i=0;i<sizeof(float);i++)
{
	float_read.b[i]=Read_AT24c02(0+i);
}

iic读写函数如下:

void Write_AT24c02(uint8_t addr,uint8_t data)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	I2CSendByte(data);
	I2CWaitAck();
	I2CStop();
}

uint8_t Read_AT24c02(uint8_t addr)
{
	uint8_t val;
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	val=I2CReceiveByte();
	I2CWaitAck();
	I2CStop();
	return val;
}

2.负数

定义共用体

union eeprom_s16
{
	int16_t a;
	uint8_t b[2];
}s16_write,s16_read;
//声明
s16_write.a = -777;

思路和浮点数一样。负数在内存中的存储和正数一样,只是最高位用于表示正负。通过拆分有符号数据,然后逐字节的存储。

for(i=0;i<sizeof(uint16_t);i++)
{
	Write_AT24c02(33+i,s16_write.b[i]);
	HAL_Delay(5);
}
for(i=0;i<sizeof(uint16_t);i++)
{
	s16_read.b[i]=Read_AT24c02(33+i);
}

 3.多种数据类型

定义共用体

union eeprom_dat
{
	uint8_t t1;
	uint16_t t2;
	uint32_t t3;
	int16_t t4;
	float f1;
	double f2;
	uint8_t str[20];
}eeprom_dat_write,eeprom_dat_read;

//声明
eeprom_dat_write.f2 = 3.1415926535;

要确保uint8_t足够大,为了各种类型都能得到安全的存储。

for(i = 0; i < sizeof(eeprom_dat_write.f2); i++)
{
	Write_AT24c02(i,eeprom_dat_write.str[i]);
	HAL_Delay(5);
}
for(i = 0; i < sizeof(eeprom_dat_write.f2); i++)
{
	eeprom_dat_read.str[i] = Read_AT24c02(i);
	
}

猜你喜欢

转载自blog.csdn.net/qq_53144843/article/details/124024862
今日推荐