我有一组值存储在相对较大类型的变量中,我必须再次将其存储在相对较小的变量中。
问题的故事如下:我有不同类型的传感器值,如uint16_t、uint32_t和float。我想将分离的值存储在uint8_t缓冲区阵列中,以便通过RF发射机进行传输。对于float类型,我接受一个有限的有效值,然后使用整数乘法将其存储在一个整数变量中。像这样:
对于这个例子,我想要逗号后面的3位数字,
float var1 = 12.3456789;
uint16_t var2;
var1 *= 1000;
var2 = (int) var1;
哪个输出:
Var2: 12345 , Var1: 12345.679688
问题的摘要可以在图中显示为,
问题摘要
其中黑框是32字节缓冲区中的uint8_t类型的元素,橙色框是uint16_t变量,我想将其分离为两个uint8_t变量。
我尝试将memcpy((用作
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int main() {
uint8_t buffer[32];
uint16_t var1 = 64000;
memcpy(&buffer[0], &var1, 1);
memcpy(&buffer[1], &var1 + 1, 1);
printf("var1: 0x%xnrbuffer[0]: 0x%xnrbuffer[1]: 0x%x", var1, buffer[0], buffer[1]);
return 0;
}
哪个输出:
var1: 0xfa00
buffer[0]: 0x0
buffer[1]: 0x0
我曾想过使用位运算符以某种方式进行分离,但失败了。如果你能为这个问题找到任何可能的解决方案,那就太好了。
所以,当你这样做时:
memcpy(&buffer[0], &var1, 1);
memcpy(&buffer[1], &var1 + 1, 1);
您实际上是在从&var1
和&var1 + 1
分别复制1个字节的数据。所以这里的大问题是";什么是&var1 + 1
&";。
由于var1
是uint16_t
,取该地址会得到uint16_t*
,因此将该指针增加一将向前跳转两个字节,而不是一个。
如果将&var1
的结果强制转换为uint8_t
:
memcpy(&buffer[0], (uint8_t*)&var1, 1);
memcpy(&buffer[1], (uint8_t*)&var1 + 1, 1);
你会得到一个可能更接近你预期的结果:
var1: 0xfa00
buffer[0]: 0x0
buffer[1]: 0xfa
如果你想对数据进行比特移位,你可以这样做:
buffer[0] = var1 & 0xFF; // mask off top 8 bits
buffer[1] = var1 >> 8; // shift top 8 bits down to bottom 8 bits
这产生了相同的结果。。。
var1: 0xfa00
buffer[0]: 0x0
buffer[1]: 0xfa
请记住,根据您的平台,如果数据源与数据使用者的表示方式不同,则可能会遇到端序问题。