CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

reverse order of bits

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

reverse order of bits
PostPosted: Thu Jun 23, 2005 8:42 am     Reply with quote

Search items swap_bits, bit order, MSB LSB, reverse order
The function swap_bits put 7->0, 6->1, 5->2...
00010011 becomes 11001000
Made some changes to shorten it up. Its now equivalent to Neutone. See below time trials
Code:

#include <16F877.h>
#device *=16
#use delay(clock=16000000)
#fuses HS,NOWDT,NOLVP,PROTECT,PUT,BROWNOUT
#use rs232(baud=19200,xmit=PIN_E0,INVERT,stream=DEBUG) // STDERR(same as DEBUG)
#case
#zero_ram
#define VER_MAJOR 1
#define VER_MINOR 00
int8 swap_bits(char data);
//=== Main ===
void main(void)
{
  char test,x,y,result;
  fprintf(DEBUG,"Starting\n\r");
  fprintf(DEBUG,"Bit swap %u.%02u\n\r",VER_MAJOR,VER_MINOR);
  while(1)
  {
    result=0;
    test++;
    fprintf(DEBUG,"t=0x%X ",test);
    fprintf(DEBUG,"r=0x%X\n\r",swap_bits(test));
  }
}


//===== swap_bits =====//
 int8 swap_bits( int8 data )
{
  int8 result=0;
  if(bit_test(data,0)) bit_set(result,7);
  if(bit_test(data,1)) bit_set(result,6);
  if(bit_test(data,2)) bit_set(result,5);
  if(bit_test(data,3)) bit_set(result,4);
  if(bit_test(data,4)) bit_set(result,3);
  if(bit_test(data,5)) bit_set(result,2);
  if(bit_test(data,6)) bit_set(result,1);
  if(bit_test(data,7)) bit_set(result,0);
  return result;
}



Last edited by treitmey on Thu Jul 12, 2007 12:26 pm; edited 3 times in total
chingB



Joined: 29 Dec 2003
Posts: 81

View user's profile Send private message

PostPosted: Sat Jun 25, 2005 12:29 am     Reply with quote

treitmey... this is of great help... reversing the endianess of the bits.
thanks.
dbotkin



Joined: 08 Sep 2003
Posts: 197
Location: Omaha NE USA

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Aug 15, 2005 9:41 am     Reply with quote

Here's what I do:

Code:
   
#asm
count = 7
fliploop:
    RRF orig_value,F
    RLF new_value,F
    DECFSZ count
    goto fliploop
#endasm


I actually set count elsewhere, since I need to reverse a variable number of bits. I think you can use this instead, if you don't like using #ASM:

Code:

for(x=0;x<8;x++) {
    shift_left(&new_value,1,shift_right(&orig_value,1,0))
}


My way uses a lot less code space, though, that's the only reason I can think of that I would resort to ASM code in the middle of a C program.

Dale
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Mon Oct 17, 2005 8:07 am     Reply with quote

another one. Shamelessly stolen from the main forum.
instead of 0->8 it goes 8->0
Code:
int8 reverse( int8 backwards )
{
  int8 result=0;
  int8 x;

  x = 8;
  do
  {
    if (bit_test(backwards,7))
      bit_set(result,0);

     rotate_left( &backwards,1);
     rotate_right( &result, 1);
  } while (--x);

  return result;
}
comvdd



Joined: 24 Nov 2005
Posts: 1

View user's profile Send private message

PostPosted: Thu Nov 24, 2005 3:27 pm     Reply with quote

why not use a ones compliment

like


BYTE this;
this =0xFF;

this = ~this;

this now = 00;

and shift/send the byte out either to your own predefined port
or to a port driver made using quickbuilder or another

i think you need to read math.h

dont forget to #include it

if you use an accumulator code that also reads the pin bits when you wish to much as inline then you can task this to bits
just call and convert

its faster.... just one convert
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Mon Nov 28, 2005 9:39 am     Reply with quote

We are reversing the ORDER of bits. not simple inverting.
TEST=0b11000000
needs to become
0b00000011

your wrong in thinking ~ will do this
TEST=~TEST
produces 0b00111111
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Feb 16, 2007 10:57 am     Reply with quote

Being curious to performance I tested the several routines from this and some other threads in a loop with 256 different values. I tested in PCWH v3.249, compiling for a PIC18F458 and meassured the timing using the simulator stopwatch.

Sorted by execution speed, fastest first:

Code:
                                              Average instruction
Version    Author                   ROM RAM   cycles per loop
-----------------------------------------------------------------
reverse_4  John Purbrick            284   0    24
reverse_3  Anonymous, Neutone        38   1    32
reverse_1  dbotkin (assembly)        18   2    63
reverse_2  Humberto, ckielstra       26   2    81
reverse_1a dbotkin (C)               32   2   120
reverse_0  Treitmey                  98   3   497

Conclusion: The lookup table method is the fastest but also uses the most memory. Dbotkin's assembly version is the smallest program but comes 3rd for speed. Neutone's version is a good compromise between code size and speed and for me the winning routine.
Note: About 4 more cycles can be saved by making the functions #inline.

Update 15-apr-2008: Treitmey's beautified version of Neutone's routine as posted on top of this thread creates exactly the same code and speed results. I like this new variant as to me it looks easier to read, but this is a matter of taste.

And here is the code used for creating the test results:
Code:
#include <18F458.h>
#FUSES HS, PROTECT,NOWDT, NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)


////////////////////////////////////////////////////////////////////////////////
// Author: treitmey
// Reference: http://www.ccsinfo.com/forum/viewtopic.php?p=76547
char reverse_0(char test)
{
  char result=0,x;
  for (x=0; x<8; x++)
  {
    if (bit_test(test,7-x))
    {
      bit_set(result,x);
    }
    else
    {
      bit_clear(result,x);
    }
  }
  return(result);
}

////////////////////////////////////////////////////////////////////////////////
// Author: dbotkin
// Reference: http://www.ccsinfo.com/forum/viewtopic.php?p=76547
int8 reverse_1( int8 orig_value )
{
  int8 count;
  int8 new_value;

  count=7;
#asm
fliploop:
    RRCF orig_value,F
    RLCF new_value,F
    DECFSZ count
    goto fliploop
#endasm 
  return new_value;
}

////////////////////////////////////////////////////////////////////////////////
// Author: dbotkin
// Reference: http://www.ccsinfo.com/forum/viewtopic.php?p=76547
int8 reverse_1a( int8 orig_value )
{
  int8 x;
  int8 new_value;

  for(x=0; x<8; x++)
  {
    shift_left(&new_value,1, shift_right(&orig_value,1,0) );
  }

  return new_value;
}


////////////////////////////////////////////////////////////////////////////////
// Authors: Humberto, ckielstra
// Reference: http://www.ccsinfo.com/forum/viewtopic.php?t=23356
int8 reverse_2( int8 backwards )
{
  int8 result=0;
  int8 x;

  x = 8;
  do
  {
    if (bit_test(backwards,7))
      bit_set(result,0);

     rotate_left( &backwards,1);
     rotate_right( &result, 1);
  } while (--x);

  return result;
}

////////////////////////////////////////////////////////////////////////////////
// Authors: Anonymous, Neutone
// Reference: http://www.ccsinfo.com/forum/viewtopic.php?t=23356
int8 reverse_3( int8 backwards )
{
  // First, we define each bit in both the backwards and forwards
  // integers.
  #bit bkwd_0 = backwards.0
  #bit bkwd_1 = backwards.1
  #bit bkwd_2 = backwards.2
  #bit bkwd_3 = backwards.3
  #bit bkwd_4 = backwards.4
  #bit bkwd_5 = backwards.5
  #bit bkwd_6 = backwards.6
  #bit bkwd_7 = backwards.7

  int forwards;
  #bit fwd_0 = forwards.0
  #bit fwd_1 = forwards.1
  #bit fwd_2 = forwards.2
  #bit fwd_3 = forwards.3
  #bit fwd_4 = forwards.4
  #bit fwd_5 = forwards.5
  #bit fwd_6 = forwards.6
  #bit fwd_7 = forwards.7


  forwards=0;
  if (bkwd_7) fwd_0=1;
  if (bkwd_6) fwd_1=1;
  if (bkwd_5) fwd_2=1;
  if (bkwd_4) fwd_3=1;
  if (bkwd_3) fwd_4=1;
  if (bkwd_2) fwd_5=1;
  if (bkwd_1) fwd_6=1;
  if (bkwd_0) fwd_7=1;

  return forwards;
}

////////////////////////////////////////////////////////////////////////////////
// Author: John Purbrick
// Reference: http://www.ccsinfo.com/forum/viewtopic.php?t=8375
int8 const reverse_4[256] =
{
  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
  0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
  0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
  0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
  0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
  0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
  0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
  0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
  0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
  0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
  0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
  0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
  0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
  0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
  0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
  0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
  0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
  0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
  0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
  0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
  0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
  0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
  0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
  0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
  0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
  0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
  0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF};

////////////////////////////////////////////////////////////////////////////////
void main()
{
  int8 result;
  int8 i;
 
  i = 0;
  do
  {
    result = reverse_0(i);
  }  while(i++<255);

  for(;;);
}
Arsenic



Joined: 23 Sep 2016
Posts: 13

View user's profile Send private message

PostPosted: Wed Oct 05, 2016 12:34 am     Reply with quote

Well, there's been a few years... now I finally made it work (?). Here, take this code and change the x values for 8 and 16 bits.

Code:

void reverse()
{

   char x;
   int1 helpme[32];                         //Store the bits.
   for( x = 0; x < 32; x++)
   {
     
      helpme[31-x] = bit_test(Data,x); //Data is any INT32 variable

   }
   for (x = 0; x < 32; x++){
      if(helpme[x]==0){
         bit_clear(DataSh,x);   //DataSh will be the result.
      }
      else{
         bit_set(DataSh,x);
      }
   
   }
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group