|
|
View previous topic :: View next topic |
Author |
Message |
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
reverse order of bits |
Posted: Thu Jun 23, 2005 8:42 am |
|
|
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
|
|
Posted: Sat Jun 25, 2005 12:29 am |
|
|
treitmey... this is of great help... reversing the endianess of the bits.
thanks. |
|
|
dbotkin
Joined: 08 Sep 2003 Posts: 197 Location: Omaha NE USA
|
|
Posted: Mon Aug 15, 2005 9:41 am |
|
|
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
|
|
Posted: Mon Oct 17, 2005 8:07 am |
|
|
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
|
|
Posted: Thu Nov 24, 2005 3:27 pm |
|
|
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
|
|
Posted: Mon Nov 28, 2005 9:39 am |
|
|
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
|
|
Posted: Fri Feb 16, 2007 10:57 am |
|
|
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
|
|
Posted: Wed Oct 05, 2016 12:34 am |
|
|
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);
}
}
}
|
|
|
|
|
|
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
|