前言:前面我提到的第一种存入nand的方式中,我们看到因为nand的驱动关于存入的入口参数是uint8_t类型的,所以需要把我们的数据都转换为uint8_t的类型存入。而我的项目中需要存储的数据大多是float和uint32_t的。那么就涉及到类型的转换。
问题:那么为什么要用到移位呢?这是第一种存储方式的部分代码:
static uint32_t AD_Value;
static uint8_t Save_Buff[4];
AD_Value = 0x01020304;
Save_Buff[0] = (uint8_t) AD_Value; //0x04
Save_Buff[1] = (uint8_t) (AD_Value >> 8); //0x03
Save_Buff[2] = (uint8_t) (AD_Value >> 16); //0x02
Save_Buff[3] = (uint8_t) (AD_Value >> 24); //0x01
AD_Value = *(uint32_t*)Save_Buff;
//之后AD_Value为0x01020304
在我的脑海中是这样的,这种操作我画一下:
放入Save_Buff后,再存入nand中,其实就是照搬了。
读出的时候强制类型转换就可以了
其实读出方式我是没有异议的,你存入的时候我也能理解,就是把四字节从第一个字节到底四个字节依次放入buffer的第一个位置到第四个位置嘛。
问题:不过为啥不能强制类型转换呢?何必一位对应一位的存。
static uint32_t AD_Value;
static uint8_t Save_Buff[4];
AD_Value = 0x01020304;
*(uint32_t*)Save_Buff = AD_Value;
//Save_Buff[0] 等于 0x04;Save_Buff[1] 等于 0x03;Save_Buff[2] 等于 0x02;Save_Buff[3] 等于 0x01;
AD_Value = *(uint32_t*)Save_Buff;
//AD_Value 等于 0x01020304;
事实证明,这样可以!
问题:那float型也可以吗?
static float AD_Value;
static uint8_t Save_Buff[4];
AD_Value = 123.45;
//AD_Value 等于 0x42F6E666
*(float*)Save_Buff = AD_Value;
//Save_Buff[0] 等于 0x66;Save_Buff[1] 等于 0xE6;Save_Buff[2] 等于 0xF6;Save_Buff[3] 等于 0x42;
AD_Value = *(float*)Save_Buff;
//AD_Value 等于 0x42F6E666
竟然也可以!那我觉得之前的方法就不太合适了吧,完全可以用强制类型转换。
那我尝试一下用memset吧,之前是不好使的
对不起,我二了,memset不是这么用的!
void *memset(void *s, int ch, size_t n);
函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。、
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。
我应该想尝试的是strcpy,就是想把一个数据放到一个地址上去。
不过这是字符串的复制啊!
原型声明:char *strcpy(char* dest, const char *src);
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间
strcpy是一种C语言的标准库函数,strcpy把含有'\0'结束符的字符串复制到另一个地址空间,返回值的类型为char*。
我应该想用的是memcpy
memcpy指的是C和C++使用的内存拷贝函数,函数原型为void *memcpy(void *destin, void *source, unsigned n);函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中,即从源source中拷贝n个字节到目标destin中。
static float AD_Value;
static uint8_t Save_Buff[4];
AD_Value = 123.45;
//AD_Value 等于 0x42F6E666
memcpy((float*)Save_Buff, &AD_Value, 4);
//Save_Buff[0] 等于 0x66;Save_Buff[1] 等于 0xE6;Save_Buff[2] 等于 0xF6;Save_Buff[3] 等于 0x42;
AD_Value = *(float*)Save_Buff;
//AD_Value 等于 0x42F6E666
这样就可以啦!
结论:强制类型转换和memcpy都可以,都要比分开移位赋值要简单得多。
还有就是,不确定哪种方式可以的时候,不妨拿一个F103的板子编个测试程序debug试一下,代码量小重新编译进入debug的时候也快一些。