2017-08-11 56 views
0

我有一个使用C的atMega1281微控制器。我有一个例程来从CAN总线上拉出4个字节来读取SPN。我能够得到4个字节,但我不能打印4个字节的数字,因为它会截断前2个字节,使其成为16位数字。我试过使用unsigned long作为声明没有成功。在AVR中使用32位数字时有什么窍门?如何合并4个字节并使用AVR在C中进行数学计算

unsigned long engine_hours_raw; 
float engine_hours_uint; 

engine_hours_raw = (OneMessage.Msg.Data[3] << 24) | (OneMessage.Msg.Data[2] << 16) | (OneMessage.Msg.Data[1] << 8) | OneMessage.Msg.Data[0]); 
engine_hours_uint = engine_hours_raw * 0.05; 

ftoa(engine_hours_uint, engHours, 1); 
UART1_Printf("Engine Hours: %s ", engHours); 
+0

只是可以肯定:你是如何打印4个字节数量? –

+0

我实际上使用ftoa将float转换为字符串,然后打印为字符串。 – Eddie

+0

@Eddie在裸机嵌入式系统上,它不需要坚持标准,因为我们知道指针是存储器中的实际地址:) –

回答

1

(OneMessage.Msg.Data[3] << 24)将0作为用于表达的默认大小是int。除非它被铸造。

而是将数据加载到long int中,然后执行移位。

engine_hours_raw = OneMessage.Msg.Data[3]; 
engine_hours_raw <<= 8; 
engine_hours_raw |= OneMessage.Msg.Data[2]; 
engine_hours_raw <<= 8; 
engine_hours_raw |= OneMessage.Msg.Data[1]; 
engine_hours_raw <<= 8; 
engine_hours_raw |= OneMessage.Msg.Data[0]; 

你也可以施放中间表现为无符号数或uint32_t的,但它只是作为乱,可能需要更长的时间。

engine_hours_raw = ((unit32_t)(OneMessage.Msg.Data[3]) << 24) | ((unit32_t)(OneMessage.Msg.Data[2]) << 16) | ((unit32_t)(OneMessage.Msg.Data[1]) << 8) | (unit32_t)(OneMessage.Msg.Data[0]); 
+0

为什么复杂呢?我们处于裸机嵌入式世界。指针和地址是众所周知的:) –

+0

此解决方案工作。我找到一份文件解释更多关于声明的细节。谢谢UncleO! – Eddie

0

有更简单,直接的方式:)

uint32_t *engine_hours_raw = (uint32_t *)OneMessage.Msg.Data; 
float engine_hours_uint = *engine_hours_raw * 0.05; 
相关问题