c - Uint32_t 的可变字节数
问题描述
我制作了这个函数,它解压收到的 I2C 消息并将各个值放入 uint32_t 数组中。当我使用固定宏函数将固定数量的 2 个字节放入 uint16_t 时,它可以工作,但我尝试使用 for 循环将任意数量的字节附加到我的值,因为不同的 i2c 数据包可能具有不同的值类型。我的问题在于我做位操作的方式,我的位知识似乎太有限了。这里的选项 2 有什么问题?
#define BytesToU16LE(B) ( \
(uint16_t)((B)[1]) << 8 \
| (uint16_t)((B)[0]) \
)
uint8_t ezi2cBuffer[100];
void unpack_i2c_packet(uint8_t nb_values_in_packet, uint8_t bytes_per_value, uint32_t * values, uint8_t buffer_head_size)
{
uint8_t current_value_bytes[bytes_per_value];
uint16_t payload_size = bytes_per_value * nb_values_in_packet;
uint8_t current_value_index = 0;
if(!nb_values_in_packet | !bytes_per_value)
return;
for(int i = 0; i < payload_size; i++)
{
current_value_bytes[(i % bytes_per_value) + buffer_head_size] = ezi2cBuffer[i + buffer_head_size]; // message head does not contain values, separate from payload
if((i % bytes_per_value) == (bytes_per_value - 1))
{
/* OPTION 1 WITH MACRO WORKS */
values[current_value_index] = BytesToU16LE(current_value_bytes);
/* OPTION 2 FOR LOOP PUTS RANDOM DATA IN MY VAR ARRAY! */
for(int bi = 0; bi < bytes_per_value; bi ++)
{
values[current_value_index] |= ((uint32_t)(current_value_bytes[bi]) << (bi * 8));
}
current_value_index++;
}
}
}
解决方案
values[current_value_index]
未在选项 2 中初始化。您应该将其初始化为零,否则循环后的值将取决于循环前的值。
/* OPTION 2 FOR LOOP PUTS RANDOM DATA IN MY VAR ARRAY! */
values[current_value_index] = 0; /* add this */
for(int bi = 0; bi < bytes_per_value; bi ++)
{
values[current_value_index] |= ((uint32_t)(current_value_bytes[bi]) << (bi * 8));
}
推荐阅读
- javascript - 我正在尝试制作一个简单的点击游戏,但全局变量不起作用
- laravel - laravel 8 markdown 电子邮件图像未显示
- python - 如何乘以从 arg(*arg) 获得的元素元组?(Python 3)
- c# - C#在最后一行追加一个字符然后一个接一个?
- python - 加密图像的变换和/或旋转
- asp.net-core - .NET Core 如何能够支持在 Windows、Linux 和 Mac 操作系统上运行?
- python - Python:获取字符串列表的列表索引计数
- java - 如何解析对象数组并将特定属性的元素保存到不同的数组?
- outlook - 加载项无法在 Mac Outlook 上静默安装
- r - 无法再在 OneDrive 上保存 R/RStudio 脚本 - Windows