Home > arduino > reverse bits in a byte

reverse bits in a byte

Working on a code for an arduino project I had the problem that the letters i had created for my 8×8 LED matrix were all mirrored. A letter looks like this:

byte letter_A[8] = { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00};

Now the rows are in the correct order (letter not upside down), but the leds of one row are wrong meaning the LSB should be the MSB. I found 3 solutions on the net which are all 3 cool in their own way:

The first version is a 1 to 1 translation of how i would do it on paper. Take the most left and swap it with the most right. Then take the second and swap it with the second last and so on …

// "00110011" becomes "11001100"
byte byteShift(byte num) {
  byte var = 0;     
  int i, x, y, p;
  int s = 8;    // number of bits in 'num'.
 
  for (i = 0; i < (s / 2); i++) {
    // extract bit on the left, from MSB
    p = s - i - 1;
    x = num & (1 << p);
    x = x >> p;  
    // extract bit on the right, from LSB
    y = num & (1 < < i);
    y = y >> i;
 
    var = var | (x < < i);       // apply x
    var = var | (y << p);       // apply y
  }
  return var;
}

The next version uses bit masks for reversing the order of bits

// Reverse the order of bits in a byte. 
// I.e. MSB is swapped with LSB, etc. 
byte Bit_Reverse( byte x ) 
{ 
    //          01010101  |         10101010
    x = ((x >> 1) & 0x55) | ((x < < 1) & 0xaa);
    //          00110011  |         11001100 
    x = ((x >> 2) & 0x33) | ((x < < 2) & 0xcc);
    //          00001111  |         11110000 
    x = ((x >> 4) & 0x0f) | ((x < < 4) & 0xf0); 
    return x;    
}

The last one is not pretty but pretty fast 😉

// 36 bytes small, inelegant assembler, but faster 
byte bitswap (byte x)
{
  byte result;
 
    asm("mov __tmp_reg__, %[in] \n\t"
      "lsl __tmp_reg__  \n\t"   /* shift out high bit to carry */
      "ror %[out] \n\t"  /* rotate carry __tmp_reg__to low bit (eventually) */
      "lsl __tmp_reg__  \n\t"   /* 2 */
      "ror %[out] \n\t"
      "lsl __tmp_reg__  \n\t"   /* 3 */
      "ror %[out] \n\t"
      "lsl __tmp_reg__  \n\t"   /* 4 */
      "ror %[out] \n\t"
 
      "lsl __tmp_reg__  \n\t"   /* 5 */
      "ror %[out] \n\t"
      "lsl __tmp_reg__  \n\t"   /* 6 */
      "ror %[out] \n\t"
      "lsl __tmp_reg__  \n\t"   /* 7 */
      "ror %[out] \n\t"
      "lsl __tmp_reg__  \n\t"   /* 8 */
      "ror %[out] \n\t"
      : [out] "=r" (result) : [in] "r" (x));
      return(result);
}

Categories: arduino Tags:
  1. No comments yet.
  1. No trackbacks yet.