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

发布于 2024-08-28 04:50:59 字数 451 浏览 2 评论 0原文

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

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

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

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

@EvilTeach的评论:我不确定确切的位模式是否有帮助,或者如何最好地格式化虽然只有文字,但我会考虑一下。

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

I have one microcontroller sampling from a lot of ADC's, and sending the measurements over a radio at a very low bitrate, and bandwidth is becoming an issue.

Right now, each ADC only give us 10 bits of data, and its being stored in a 16-bit integer. Is there an easy way to pack them in a deterministic way so that the first measurement is at bit 0, second at bit 10, third at bit 20, etc?

To make matters worse, the microcontroller is little endian, and I have no control over the endianness of the computer on the other side.

EDIT: So far, I like @MSN's answer the best, but I'll respond to the comments

@EvilTeach: I'm not sure if the exact bit pattern would be helpful, or how to best format it with text only, but I'll think about it.

@Jonathan Leffler: Ideally, I'd pack 8 10-bit values into 10 8-bit bytes. If it makes processing easier, I'd settle for 3 values in 4 bytes or 6 values in 8 bytes (although the 2 are equivalent to me, same amount of 'wasted' bits)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦毁影碎の 2024-09-04 04:50:59

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

Use bit 0 and 31 to determine endianness and pack 3 10-bit values in the middle. One easy way to test matching endianness is to set bit 0 to 0 and bit 31 to 1. On the receiving end, if bit 0 is 1, assert that bit 31 is 0 and swap endianness. Otherwise, if bit 0 is 0, assert that bit 31 is 1 and extract the 3 values.

沙沙粒小 2024-09-04 04:50:59

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

也就是说,它看起来像:

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

编辑:已更正,感谢乔纳森。

You can use bitfields, but the ordering within machine words is not defined:

That said, it would look something like:

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

EDIT: Corrected, thanks to Jonathan.

你的笑 2024-09-04 04:50:59

关于字节序最简单的做法就是简单地选择一个用于传输。要打包传输流中的位,请使用累加器(在您的情况下至少有 17 位),在该累加器中一次移入 10 位并跟踪其中有多少位。当您传输一个字节时,您从累加器中取出一个字节,从计数中减去 8,并将累加器移位 8。我在这里宽松地使用“传输”,您可能将其存储到缓冲区中以供以后传输。

例如,如果传输是小端字节序,则您将移入累加器顶部的 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

接收是类似的拆包操作。

The simplest thing to do about endian-ness is to simply pick one for your transmission. To pack the bits in the transmission stream, use an accumulator (of at least 17 bits in your case) in which you shift in 10 bits at a time and keep track of how many bits are in it. When you transmit a byte, you pull a byte out of the accumulator, subtract 8 from your count, and shift the accumulator by 8. I use "transmit" here loosely, your probably storing into a buffer for later transmission.

For example, if transmission is little endian, you shift in your 10 bits at the top of the acccumator (in its MS bits), and pull your bytes from the bottom. For example: for two values a and 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

Reception is a similar unpacking operation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文