这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » 在51单片机中的数据数据拷贝的几种方法

共1条 1/1 1 跳转至

在51单片机中的数据数据拷贝的几种方法

高工
2025-10-26 09:04:58   被打赏 20 分(兑奖)     打赏

    最近在使用STC的单片机做项目,用到了STC的内部eeprom的数据存储。为了使代码看起来精简,移植性起来更加的方便,这里我是用结构体的方式进行数据的存储、读取和显示。由于之前在使用外扩的存储芯片的方式,将结构体转换成数据的方式进行数据的处理,看起来要更加的简练。就想着在51单片机里移植一下。

方法1:使用库函数里面的memcpy函数。

#include <string.h> //定义包含主函数

// 定义结构体
typedef struct {
    unsigned char  number1;
    unsigned int   number2;
    unsigned long  number3;
} MyStructData;

 MyStructData   MyStructData1;
uint8_t Data[sizeof(MyStructData)];

// 拷贝结构体到数组
memcpy(Data, &MyStructData, sizeof(MyStructData));

方法2:使用指针的方式,将字节逐个进行拷贝

// 定义结构体
typedef struct {
    uint8_t id;
    uint16_t value;
    uint8_t status;
} SensorData;

SensorData sensor = {0x01, 1234, 0xAA};
uint8_t dataBuffer[sizeof(SensorData)];

// 使用指针拷贝
void copyStructToArray(void *dest, void *src, size_t size) {
    uint8_t *d = (uint8_t *)dest;
    uint8_t *s = (uint8_t *)src;
    for(size_t i = 0; i < size; i++) {
        d[i] = s[i];
    }
}

// 调用拷贝函数
copyStructToArray(dataBuffer, &sensor, sizeof(SensorData));

方法3:按照变量的方式逐个拷贝

typedef struct {
    float temperature;
    float humidity;
    uint16_t pressure;
} WeatherData;

WeatherData weather = {25.5, 60.2, 1013};
uint8_t transmitBuffer[10]; // 确保数组足够大

// 手动拷贝每个成员
void copyWeatherDataToArray(WeatherData *wd, uint8_t *array) {
    // 拷贝temperature (4字节)
    memcpy(&array[0], &wd->temperature, 4);
    // 拷贝humidity (4字节)
    memcpy(&array[4], &wd->humidity, 4);
    // 拷贝pressure (2字节)
    memcpy(&array[8], &wd->pressure, 2);
}

// 调用函数
copyWeatherDataToArray(&weather, transmitBuffer);

方法4:使用联合结构体的方式

typedef struct {
    uint8_t cmd;
    uint16_t param1;
    uint16_t param2;
} CommandStruct;

typedef union {
    CommandStruct cmdStruct;
    uint8_t byteArray[sizeof(CommandStruct)];
} CommandUnion;

CommandUnion myCmd;

// 直接访问
myCmd.cmdStruct.cmd = 0x10;
myCmd.cmdStruct.param1 = 1000;
myCmd.cmdStruct.param2 = 2000;

// 现在myCmd.byteArray就是对应的字节数组
uint8_t *arrayPtr = myCmd.byteArray;

使用过程中需要注意的几点:

大小端问题:考虑处理器的字节序

数组大小:确保目标数组足够大

性能考虑:对于实时性要求高的场景,选择最合适的方法

实际使用代码如下所示:

2.1 存储历史数据代码如下:

void SaveTestData(int Value)
{
	int count = sizeof(SaveResulutValue) ;
	unsigned char xdata WriteBuf[sizeof(SaveResulutValue)];
	int i = 0;
	int SaveAddr;
	memset(WriteBuf,0,sizeof(SaveResulutValue));
//	memcpy(&ReadBuf[0],&ResulutValue,sizeof(ResulutValue));		
	memcpy(WriteBuf,&ResulutValue,count)	;	
	IapErase(RESULTDATAADD + 512*Value)
	SaveAddr = RESULTDATAADD + 512*Value;
	for(i = 0; i < count; i++)
	{
		IapProgram(SaveAddr,WriteBuf[i]);
		SaveAddr++;
	}	
}

2.2 读取历史数据代码如下:

void ReadTestData(int Value)
{
	int count = sizeof(ReadResulutValue) ;
	unsigned char xdata ReadBuf[sizeof(ReadResulutValue)];
	int i = 0;
	int ReadAdd;
 	ReadAdd = RESULTDATAADD + 512*Value;
	for(i = 0; i < count; i++)
	{
		ReadBuf[i] = IapRead(ReadAdd);
		ReadAdd++;	
	}
  memcpy(&ReadResulutValue,ReadBuf,sizeof(ReadResulutValue))	;
}





关键词: 单片机     数据拷贝    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]