Recently, I encountered the issue of byte endianness conversion in a protocol, so I lazily searched online and found a similar problem, and learned a new term called butterfly swapping.
The problem is as follows:
The protocol requires that the low byte is on the left and the high byte is on the right, and each byte needs to be processed by swapping its high and low bits. For example, 11010001
becomes 10001011
after swapping the corresponding bits 0->7, 1->6, 2->5, 3->4
.
This requires knowledge of bit manipulation, refer to What are the tricks of bit manipulation? (with source code)
Here we take the 8-bit data high-low bit conversion as an example:
1#include <stdio.h>
2
3unsigned char highAndLowShiftHEX(unsigned char data);
4void printBin(int n);
5
6int main () {
7
8 highAndLowShiftHEX(209);
9 return 0;
10}
11
12unsigned char highAndLowShiftHEX(unsigned char data)
13{
14 unsigned char i;
15 unsigned char tmp=0x00;
16 for(i=0;i<8;i++)
17 {
18 tmp=((data>>i)&0x01)|tmp;
19 //printBin(tmp);
20 if(i<7)
21 tmp=tmp<<1;
22 }
23 printf("\nafter shift data:");
24 printBin(tmp);
25 return tmp;
26}
27
28// Since binary is intuitive, a function to print binary is written
29void printBin(int n)
30{
31 int len = sizeof(n)*8;// Total bits.
32 int i;
33 if(i == 0)
34 {
35 printf("0");
36 return;
37 }
38 for(i = len-1; i >= 0; i --)// Omit high bits 0.
39 {
40 if(n&(1<<i)) break;
41 }
42
43 for(;i>=0; i --)
44 printf("%d", (n&(1<<i)) != 0);
45}
Familiarity with bit manipulation makes the implementation of the above code relatively simple. In embedded development, such problems are usually solved using the butterfly swapping method and lookup table method.
Higher-level implementation?
The lookup table method involves storing some values in memory and looking them up when needed, but this method consumes additional storage space.
Therefore, we mainly introduce the butterfly swapping method, taking 8-bit data conversion as an example.
-
Assuming the original sequence is:
1 2 3 4 5 6 7 8
-
The target sequence is:
8 7 6 5 4 3 2 1
The flowchart is as follows:

This completes the entire bit’s reverse conversion. Similarly, taking 11010001
as an example, here is the specific implementation code:
1#include <stdio.h>
2
3unsigned char highAndLowShiftHEX(unsigned char );
4void printBin(int );
5
6int main () {
7
8 highAndLowShiftHEX(209);
9 return 0;
10}
11
12unsigned char highAndLowShiftHEX(unsigned char data)
13{
14 data=(data<<4)|(data>>4);
15 data=((data<<2)&0xcc)|((data>>2)&0x33);
16 data=((data<<1)&0xaa)|((data>>1)&0x55);
17 printf(" after shift data=%x \n",data);
18 printBin(data);
19 return data;
20}
21
22// Since binary is intuitive, a function to print binary is written
23void printBin(int n)
24{
25 int len = sizeof(n)*8;// Total bits.
26 int i;
27 if(i == 0)
28 {
29 printf("0");
30 return;
31 }
32 for(i = len-1; i >= 0; i --)// Omit high bits 0.
33 {
34 if(n&(1<<i)) break;
35 }
36
37 for(;i>=0; i --)
38 printf("%d", (n&(1<<i)) != 0);
39}
Swapping the high and low bits of bytes is not a very common problem. When encountering this issue, careful analysis and a good grasp of C language bit manipulation can effectively solve such problems.
Extension
Now, let’s extend this to the high-low bit conversion of 16-bit half-word data.
The principle is actually the same as for 8 bits, using simple shifting to convert the high and low bits of the data. If you are familiar with bit manipulation, the code becomes relatively simple.
Here is the specific implementation of this idea:
1#include <stdio.h>
2
3void expandPrintBin(int val2);
4unsigned short HighAndLowSwitchHEX(unsigned short data);
5
6int main () {
7
8 HighAndLowSwitchHEX(38491);
9 return 0;
10}
11
12
13// Since binary is intuitive, a function to print binary is written
14void expandPrintBin(int val2)
15{
16 int i,k;
17 unsigned char *p = (unsigned char*)&val2 + 3; // From low to high, low-end byte computer
18 for( k = 0; k <= 3; k++)
19 {
20 int val2 = *(p-k);
21 for (i = 7; i >= 0; i--)
22 {
23 if(val2 & (1 << i))
24 printf("1");
25 else
26 printf("0");
27 }
28 printf(" ");
29 }
30}
31unsigned short HighAndLowSwitchHEX(unsigned short data)
32{
33 unsigned char i = 0;
34 unsigned short temp = 0x0000;
35
36 for(i = 0; i < 16; i++)
37 {
38 temp = ((data >> i) & 0x0001) | temp;
39 if(i < 15)
40 {
41 temp = temp << 1;
42 }
43 }
44 printf("temp:%x\n\n",temp);
45 expandPrintBin(temp);
46 return temp;
47}
Similarly, the so-called butterfly swapping method, I referenced the byte swapping method example, we can calculate as follows:
-
Assuming the original sequence is:
a b c d e f g h i j k l m n o p
-
The target sequence is:
p o n m l k j i h g f e d c b a
The flowchart is shown below:

This completes the entire bit’s reverse conversion, completing the algorithm’s extension. Taking 1001011001011011
as an example, here is the specific implementation code:
1#include <stdio.h>
2
3unsigned short highAndLowShiftHEX(unsigned short data);
4void expandPrintBin(int val2);
5
6int main () {
7
8 highAndLowShiftHEX(38491);
9 return 0;
10}
11
12unsigned short highAndLowShiftHEX(unsigned short data)
13{
14 data = (data << 8) | (data >> 8); //0101101110010110
15 data = ((data << 4) & 0xF0FF) | ((data >> 4) & 0xFF0F); //1011010101101001
16 data = ((data << 2) & 0xCCCC) | ((data >> 2) & 0x3333); //1110010110010110
17 data = ((data << 1) & 0xAAAA) | ((data >>1 ) & 0x5555); //1101101001101001
18 printf(" after shift data=%x \n",data);
19 expandPrintBin(data);
20 return data;
21}
22
23// Since binary is intuitive, a function to print binary is written
24void expandPrintBin(int val2)
25{
26 int i,k;
27 unsigned char *p = (unsigned char*)&val2 + 3; // From low to high, low-end byte computer
28 for( k = 0; k <= 3; k++)
29 {
30 int val2 = *(p-k);
31 for (i = 7; i >= 0; i--)
32 {
33 if(val2 & (1 << i))
34 printf("1");
35 else
36 printf("0");
37 }
38 printf(" ");
39 }
40}
For such bit swapping problems, they are often encountered in embedded development. Familiarity with bit manipulation and debugging techniques is very important. Proficient use of C language shifting operations can quickly solve such problems.
Conclusion
The key to the above problem is the flexible use of bit manipulation. Additionally, two functions for printing binary were written for convenience. The code can be used directly, and debugging is not easy. Please feel free to like!
ENDAuthor: Li XiaoyaoSource: Technology Makes Dreams GreaterCopyright belongs to the original author. If there is any infringement, please contact for deletion.▍Recommended ReadingDon’t underestimate 8-bit microcontrollers!If I write another for loop, I will hammer myself!These embedded software testing tools are so good they take off~→ Follow to avoid getting lost ←