【发布时间】:2017-03-25 15:34:57
【问题描述】:
void OPC_N2_data_read()
{
unsigned int32 iobyte[3][4] = {0x00, };
int32 PM_int[3] = {0x00, };
float PM[3] = {0x00, };
int8 i,j,k;
int8 mask = 0x80;
const int16 mask1 = 0x0001;
const int16 mask0 = 0x0000;
int8 trash_byte = 0x32;
output_bit(ss,1);
output_bit(PM_CLOCK_pin,0);
delay_us (1);
output_bit(ss,0);
delay_us (2);
for( i = 0 ; i < 3 ; i ++ )
{
for ( j = 0 ; j < 4 ; j ++ )
{
for (k = 0 ; k < 8 ; k ++ )
{
output_bit(PM_CLOCK_pin,1);
iobyte[i][j] = iobyte[i][j] << 1;
if ( input ( PM_MISO_pin))
{
iobyte[i][j] |= mask1;
}
else
{
iobyte[i][j] |= mask0;
}
if ((trash_byte & mask) >0)
{
output_high(PM_MOSI_pin);
}
else
{
output_bit(PM_MOSI_pin,0);
}
delay_us(1);
output_bit(PM_CLOCK_pin,0);
delay_us(5);
mask = mask >>1;
}
}
}
delay_us(3);
output_high(ss);
for(i = 0; i<3; i++)
{
PM_int[i] = ((iobyte[i][0]<<24)|(iobyte[i][1]<<16)|(iobyte[i][2]<<8)|(iobyte[i][3]));
PM[i] = *(float*)&PM_int;
}
printf ("%x%x%x%x\r\n",iobyte[0][0],iobyte[0][1],iobyte[0][2],iobyte[0][3]);
printf ("%x%x%x%x\r\n",iobyte[1][0],iobyte[1][1],iobyte[1][2],iobyte[1][3]);
printf ("%x%x%x%x\r\n",iobyte[2][0],iobyte[2][1],iobyte[2][2],iobyte[2][3]);
printf ("%lx,%lx,%lx\r\n", PM_int[0],PM_int[1],PM_int[2]);
printf ("%3.5f,%3.5f,%3.5f\r\n", PM[0],PM[1],PM[2]);
}
我从一个 4 字节数组接收数据。 该数据是一个浮点值。 我通过电脑查看,我看到以下内容。
e911bd41 d867e641 8084e941 e911bd41,d867e641,8084e941 0.00000,0.00000,0.00000
将四个数据变成一个 INT 值可以正常工作。 PM_int[0],PM_int[1],PM_int[2]
但是,如果您尝试将其转换为浮点值,则只会显示 0.00000。
我不知道问题出在哪里。
【问题讨论】:
-
@user694733:
memcpy也破坏了它们。唯一完全合法的类型双关语是union。尽管如此,OP 应该使用适当的(反)序列化,使用位移位和掩码到uint32_t,然后使用union。 -
1) 不要使用有符号整数进行位移。某些值将调用未定义的行为,对于其他值,结果是实现定义的。 2)对固定宽度类型使用标准类型,没有自制的东西!见
stdint.h -
@Olaf
memcpy根据字符类型工作。 7.24.2.1 p2:“memcpy 函数将 n 字符从 s2 指向的对象复制到 s1 指向的对象中。” 将任何数据指针类型转换为@987654336 @ 定义明确。您给出的规则适用于通过不同类型访问 same 对象。 -
@Olaf 众所周知,
memcpy从一个变量到另一个不同类型的变量是完全合法的。您断言“memcpy 在此处具有赋值运算符的语义”是不合理的。在所有其他方面memcpy的行为就好像它通过char *进行复制一样,这在某种程度上被函数的定义所暗示。您肯定会认识到通过char *复制是合法的(在6.5 中强制要求这样做),建议等效的memcpy行为不同是站不住脚的。我认为没有理由假设memcpy会导致通过char以外的任何其他类型进行访问。 -
此外,告诉@user694733“做一些研究”是荒谬的,因为几乎所有关于该主题的完整讨论都提到使用
memcpy的合法性。例如,dbp-consulting.com/tutorials/StrictAliasing.html; stackoverflow.com/questions/3275353/c-aliasing-rules-and-memcpy 上接受的答案; blog.regehr.org/archives/1307(“通过字符数组检查对象的表示总是可以的。这是使类似 memcpy 的函数正常工作所必需的”)。
标签: c arrays type-conversion