简体   繁体   English

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

[英]Creating a byte (8 bits) from 4 2 bits

I am trying to figure out a way to get as much out of the limited memory in my microcontroller (32kb) and am seeking suggestions or pointers to an algorithm that performs what I am attempting to do. 我试图找出一种方法来从我的微控制器(32kb)中的有限内存中获取尽可能多的内容,并且正在寻找建议或指向执行我尝试执行的操作的算法。

Some background: I am sending Manchester Encoded bits out a SPI (Serial Peripheral Interface) directly from DMA. 一些背景:我直接从DMA发送曼彻斯特编码位SPI(串行外设接口)。 As the smallest possible unit I can store data into DMA is a byte (8 bits), I am having to represent my 1's as 0b11110000 and my 0's as 0b00001111. 作为尽可能小的单元,我可以将数据存储到DMA中是一个字节(8位),我必须将我的1表示为0b11110000而将我的0表示为0b00001111。 This basically means that for every bit of information, I need to use a byte (8 bits) of memory. 这基本上意味着对于每一位信息,我需要使用一个字节(8位)的内存。 Which is very inefficient. 这是非常低效的。

If I could reduce this, so that my 1's are represented as 0b10 and my 0's as 0b01, I'd only have to use a 1/4 of a byte (2 bits) for every 1 bit of memory, which is fine for my solution. 如果我可以减少这个,那么我的1表示为0b10而我的0表示为0b01,我只需要为每1位内存使用1/4字节(2位),这对我来说很好解。

Now, if I could save to DMA in bits, this would not be a problem, but of course I need to work with bytes. 现在,如果我可以保存到位的DMA,这不会是一个问题,但当然我需要使用字节。 So I know the solution to my problem involves collecting the 8 bits (or in my case, 4 2bits) and then storing to DMA as a byte. 所以我知道我的问题的解决方案涉及收集8位(或者在我的情况下,4个2位)然后作为一个字节存储到DMA。

Questions: 问题:

Is there a standard way to solve this problem? 有没有一种标准的方法可以解决这个问题?

How can I some how create a 8 bit number from a collection of 4 2 bit numbers? 我怎样才能从4个2位数字的集合中创建一个8位数? But I do not want the addition of these numbers, but the actual way it looks when collected together. 但我不希望增加这些数字,而是收集在一起时的实际看法。

For example: I have the following 4 2 bit numbers (keeping in mind that 0b10 represents 1 and 0b01 represents 0) (Also, the type these are stored in is open to the solution, as obviously there is no such thing as a 2 bit type) 例如:我有以下4个2位数字(记住0b10代表1而0b01代表0)(另外,存储的类型对解决方案是开放的,因为显然没有2位这样的东西类型)

Number1: 0b01 Number 2: 0b10 Number 3: 0b10 Number4: 0b01 Number1: 0b01 Number 2: 0b10 Number 3: 0b10 Number4: 0b01

And I want to create the following 8 bit number from these: 我想从这些中创建以下8位数:

8 Bit Number: 0b01 10 10 01 or without the spaces 0b01101001 (0x69) 8位号: 0b01 10 10 01或没有空格0b01101001(0x69)

I am programming in c 我在c编程

It seems that you can pack four numbers a , b , c , d , all of which of value zero or one, like so: 看来你可以打包四个数字abcd ,所有数值为零或一,如下:

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

This is using the fact that x + 1 encodes your two-bit integer: 1 becomes 0b10, and 0 becomes 0b01. 这是使用x + 1对两位整数进行编码的事实:1变为0b10,0变为0b01。

It's Manchester encoding so 0b11110000 and 0b00001111 should be the only candidates. 它是曼彻斯特编码所以0b11110000和0b00001111应该是唯一的候选者。 If so, then reduce the memory by a factor of 8. 如果是这样,那么将内存减少8倍。

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

Other other hand, if it's Manchester encoding and one may not have perfect encoding, then there are 3 results: 0, 1, indeterminate. 另一方面,如果它是曼彻斯特编码而其中一个可能没有完美的编码,则有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();
}

Various simplifications absent in the above, but shown for logic flow. 上面没有各种简化,但是针对逻辑流程进行了说明。

To number get abcd from (a,b,c,d) you need to shift the number to their places and OR :- 要编号从(a,b,c,d)获取abcd,您需要将数字移到他们的位置并且OR: -

(a<<6)|(b<<4)|(c<<2)|d (A << 6)|(B << 4)|(C << 2)| d

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM