最近在使用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)) ;
}2.3 按字节存储变量数据:
void SaveTestParameter(void)
{
int iAdd = SYSTEMNUMBERADD;
int SaveAddr;
SaveAddr = SYSTEMNUMBERADD ;
IapErase(SaveAddr);
IapProgram(SaveAddr,SystemParaSet.iSystemPointTime >>8) ; SaveAddr++ ;
IapProgram(SaveAddr,SystemParaSet.iSystemPointTime) ; SaveAddr++ ;
IapProgram(SaveAddr,SystemParaSet.iSystemMaxTime >>8) ; SaveAddr++ ;
IapProgram(SaveAddr,SystemParaSet.iSystemMaxTime); SaveAddr++ ;
IapProgram(SaveAddr,SystemParaSet.iSystemPointData >>8) ; SaveAddr++ ;
IapProgram(SaveAddr,SystemParaSet.iSystemPointData) ; SaveAddr++ ;
IapProgram(SaveAddr,SystemParaSet.iSystemMaxData >>8) ; SaveAddr++ ;
IapProgram(SaveAddr,SystemParaSet.iSystemMaxData); SaveAddr++ ;
IapProgram(SaveAddr,SystemParaSet.iSystemEmptyTime >>8) ; SaveAddr++ ;
IapProgram(SaveAddr,SystemParaSet.iSystemEmptyTime); SaveAddr++ ;
IapProgram(SaveAddr,CurrePoint>> 8 ) ; SaveAddr++ ;
IapProgram(SaveAddr,CurrePoint); SaveAddr++ ;
}2.4 读取字节数据信息:
void ReadTestParameter(void)
{
int iAdd = SYSTEMNUMBERADD;
int ReadAddr;
ReadAddr = SYSTEMNUMBERADD ;
SystemParaSet.iSystemPointTime = IapRead(ReadAddr ); ReadAddr++ ;
SystemParaSet.iSystemPointTime = (SystemParaSet.iSystemPointTime << 8) + IapRead(ReadAddr) ; ReadAddr++ ;
SystemParaSet.iSystemMaxTime = IapRead(ReadAddr ); ReadAddr++ ;
SystemParaSet.iSystemMaxTime = (SystemParaSet.iSystemMaxTime << 8) + IapRead(ReadAddr) ; ReadAddr++ ;
SystemParaSet.iSystemPointData = IapRead(ReadAddr ); ReadAddr++ ;
SystemParaSet.iSystemPointData = (SystemParaSet.iSystemPointData << 8) + IapRead(ReadAddr) ; ReadAddr++ ;
SystemParaSet.iSystemMaxData = IapRead(ReadAddr ); ReadAddr++ ;
SystemParaSet.iSystemMaxData = (SystemParaSet.iSystemMaxData << 8) + IapRead(ReadAddr) ; ReadAddr++ ;
SystemParaSet.iSystemEmptyTime = IapRead(ReadAddr ); ReadAddr++ ;
SystemParaSet.iSystemEmptyTime = (SystemParaSet.iSystemEmptyTime << 8) + IapRead(ReadAddr) ; ReadAddr++ ;
CurrePoint = IapRead(ReadAddr ); ReadAddr++ ;
CurrePoint = (CurrePoint << 8) + IapRead(ReadAddr) ; ReadAddr++ ;
}从上面的代码可以看到,使用memcpy函数,不仅方便,使代码更加简洁,也不容易出错。
我要赚赏金
