在C中创建/解压缩大型位域的有效方法?

时间:2010-04-05 01:35:03

标签: c portability bitmask

我有一个微控制器的微控制器采样,并以非常低的比特率通过无线电发送测量结果,带宽正成为一个问题。

现在,每个ADC只给我们10位数据,并以16位整数存储。是否有一种简单的方法以确定的方式打包它们,以便第一次测量位于第0位,第二位在第10位,第三位在第20位,等等?

更糟糕的是,微控制器是小端的,我无法控制另一端计算机的字节序。

编辑:到目前为止,我最喜欢@ MSN的答案,但我会回复评论

@EvilTeach:我不确定确切的位模式是否有用,或者如何使用纯文本进行最佳格式化,但我会考虑它。

@Jonathan Leffler:理想情况下,我将8个10位值打包成10个8位字节。如果它使处理更容易,我将满足4个字节中的3个值或8个字节中的6个值(尽管2相当于我,相同数量的'浪费'位)

3 个答案:

答案 0 :(得分:4)

使用位0和31确定字节顺序并在中间打包3个10位值。测试匹配字节顺序的一种简单方法是将位0设置为0,将位31设置为1.在接收端,如果位0为1,则断言位31为0并交换字节序。否则,如果位0为0,则断言位31为1并提取3个值。

答案 1 :(得分:3)

您可以使用位域,但未定义机器字内的排序:

那就是说,它看起来像是:

struct adc_data { 
unsigned first :10;
unsigned second :10; 
unsigned third :10; 
};

编辑:更正了,感谢Jonathan。

答案 2 :(得分:0)

最简单的关于endian-ness的事情就是简单地选择一个用于传输。要打包传输流中的位,请使用累加器(在您的情况下至少为17位),其中您一次移位10位,并跟踪其中的位数。当你发送一个字节时,你从累加器中拉出一个字节,从你的计数中减去8,然后将累加器移动8.我在这里松散地使用“发送”,你可能存储到缓冲区中以便以后传输。

例如,如果传输是小端,则移位到acccumator顶部的10位(在其MS位中),并从底部提取字节。例如:对于两个值a和b:

Accumulator     Count
(MS to LS bit)   
aaaaaaaaaa      10      After storing a
aa              2       After sending first byte
bbbbbbbbbbaa    12      After storing b
bbbb            4       After sending second byte

接收是类似的拆包操作。