一、场景需求:
因为使用8位FRAM做数据缓存,但采样数据是16位,需要将u16类型数据存入u8类型的数组,考虑到数据存入后还需要读取,且采样通道数量会变化,要方便添加更改,所以采用结构体的形式直接将结构体整个数据存入u8类型数组,最后通过spi存入FRAM。
二、原理:
本质上,无论是数组还是结构体,都是一块内存,所以无论怎么存入,只要读取的顺序一致,就能确保数据准确。c语言中恰好有库函数memcpy(),此函数的作用就是将一块内存复制到另一块内存,声明如下。
void *memcpy(void *str1, const void *str2, size_t n)
str1 – 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
str2 – 指向要复制的数据源,类型强制转换为 void* 指针。
n – 要被复制的字节数。
三、示例:
#include "stdio.h"
#include "string.h"
typedef struct
{
__int16 a;
__int16 b;
}test;
int main()
{
printf("*******************************************\n");
__int8 test3[4];
test struTest3 = {1234,5678};
memcpy(test3, &struTest3, sizeof(struTest3));
printf("struTest3.a = %x\n",struTest3.a);
printf("struTest3.b = %x\n",struTest3.b);
printf("test3[0] = %x\n", test3[0]);
printf("test3[1] = %x\n", test3[1]);
printf("test3[2] = %x\n", test3[2]);
printf("test3[3] = %x\n", test3[3]);
test struTest3_1;
memcpy(&struTest3_1, &test3, sizeof(test3));
printf("struTest3_1.a = %x\n",struTest3_1.a);
printf("struTest3_1.b = %x\n",struTest3_1.b);
printf("*******************************************\n");
__int8 test4[4] = {12,34,56,78};
test struTest4;
memcpy(&struTest4, test4, sizeof(test4));
printf("test4[0]= %x\n", test4[0]);
printf("test4[1]= %x\n", test4[1]);
printf("test4[2]= %x\n", test4[2]);
printf("test4[3]= %x\n", test4[3]);
printf("struTest4.a = %x\n", struTest4.a);
printf("struTest4.b = %x\n", struTest4.b);
__int8 test4_1[4];
memcpy(test4_1, &struTest4, sizeof(struTest4));
printf("test4_1[0]= %x\n", test4_1[0]);
printf("test4_1[1]= %x\n", test4_1[1]);
printf("test4_1[2]= %x\n", test4_1[2]);
printf("test4_1[3]= %x\n", test4_1[3]);
return 0;
}
运行结果:
*******************************************
struTest3.a = 4d2
struTest3.b = 162e
test3[0] = ffffffd2
test3[1] = 4
test3[2] = 2e
test3[3] = 16
struTest3_1.a = 4d2
struTest3_1.b = 162e
*******************************************
test4[0]= c
test4[1]= 22
test4[2]= 38
test4[3]= 4e
struTest4.a = 220c
struTest4.b = 4e38
test4_1[0]= c
test4_1[1]= 22
test4_1[2]= 38
test4_1[3]= 4e
四、结论:
证明memcpy函数可以用来做不同数据类型的互相转换,虽然过程中一些量可能因为大小端存储方式的不同而有差异,但本次场景我只需要16位—>8位存入—>16位读取,不需要中间量,所以省去了16转8位的移位计算。
补充:memcpy对结构体数据复制到数组内还应有其他要求,比如结构体数据对齐,结构体指针成员等,这些可能在复制过程中出错,这里我就不验证了。