从4 2位创建一个字节(8位)

时间:2014-01-23 00:27:53

标签: c algorithm binary spi dma

我正试图找出一种方法来从微控制器(32kb)中的有限内存中获取尽可能多的内容,并且正在寻求建议或指向执行我正在尝试的算法的算法。

一些背景知识:我直接从DMA向SPI(串行外设接口)发送曼彻斯特编码位。作为尽可能小的单元,我可以将数据存储到DMA中是一个字节(8位),我必须将我的1表示为0b11110000而将我的0表示为0b00001111。这基本上意味着对于每一位信息,我需要使用一个字节(8位)的内存。这是非常低效的。

如果我可以减少这个,那么我的1表示为0b10而我的0表示为0b01,我只需要为每1位内存使用1/4字节(2位),这是我的解决方案很好。

现在,如果我可以用比特保存到DMA,这不会有问题,但当然我需要使用字节。所以我知道我的问题的解决方案涉及收集8位(或者在我的情况下,4个2位)然后作为一个字节存储到DMA。

问题:

是否有解决此问题的标准方法?

如何从4个2位数字的集合中创建8位数?但我不希望增加这些数字,而是收集它们时的实际看法。

例如:我有以下4个2位数字(请记住,0b10代表1,0b01代表0)(此外,存储的类型对解决方案是开放的,如显然没有2位类型的东西)

数字1: 0b01 数字2: 0b10 数字3: 0b10 数字4: 0b01

我想从这些中创建以下8位数字:

8位数: 0b01 10 10 01或没有空格0b01101001(0x69)

我在c

编程

3 个答案:

答案 0 :(得分:1)

您似乎可以打包四个数字abcd,其中所有值为零或一,如下所示:

64 * (a + 1) + 16 * (b + 1) + 4 * (c + 1) + (d + 1)

这是使用x + 1对您的两位整数进行编码的事实:1变为0b10,0变为0b01。

答案 1 :(得分:1)

这是曼彻斯特编码所以0b11110000和0b00001111应该是唯一的候选者。如果是这样,那么将内存减少8倍。

uint8_t PackedByte = 0;
for (i=0; i<8; i++) {
  PackedByte <<= 1;
  if (buf[i] == 0xF0) //  0b11110000
    PackedByte++;
}

另一方面,如果它是曼彻斯特编码而且可能没有完美编码,则有3个结果:0,1,不确定。

uint8_t PackedByte = 0;
for (i=0; i<8; i++) {
  int upper = BitCount(buf[i] >> 4);
  int lower = BitCount(buf[i] & 0xF);
  if (upper > lower)
    PackedByte++;
  else if (upper == lower)
    Hande_Indeterminate();
}

上面没有各种简化,但是逻辑流程显示了这些简化。

答案 2 :(得分:1)

要编号从(a,b,c,d)获取abcd,您需要将数字移到他们的位置并且OR: -

  

(A&LT;&10 6)|(b将&LT; 4)|(℃下;&2)| d