1. Recall the structure first
We all know that a structure can be defined in this way:
struct Point { float x; float y; } point; //Equivalent to: struct Point point;
In addition, if you don't want to declare a structure and just want to define it, you can do the following:
struct { float x; float y; } point; //Equivalent to: struct Point point;
2. Simple application of bit field
When we are at the lower level, we often read and write registers, such as operating a bit, which is set to 0 or 1. In C language, we are provided with a data structure "bit field", which enables us to operate a bit by reading and writing "bit field"
For example, a common bit field structure, the operation is as follows:
#include <stdio.h> struct { unsigned mode:8; //bit[0,7]:Mode selection unsigned en:1; //bit[8] :Enabling choice unsigned reserved:1; //bit[9] :Retain reserved (It can also be written as unsigned reserved:1;) unsigned clk_select:4; //bit[10,13]:Clock selection unsigned ch_select:3; //bit[14,15]:Channel selection }reg11; //Define a reg11 variable,The advantage of not declaring a struct is to ensure that variables are unique int main() { reg11.en =1; //bit8=1 --> 256 printf("reg11=%d\n",reg11); //Print 256 reg11.mode =50; printf("reg11=%d\n",reg11); //Print 256+50 return 0; }
Print:
3. Boundary crossing
For example, a bit field defined by us has only one fixed bit. If a value of more than one bit is written to the bit, the lowest bit will be retained automatically
Example:
#include <stdio.h> struct { unsigned mode:8; //bit[0,7]:Mode selection unsigned en:1; //bit[8] :Enabling choice unsigned reserved:1; //bit[9] :Retain reserved(It can also be written as unsigned reserved:1;) unsigned clk_select:4; //bit[10,13]:Clock selection unsigned ch_select:3; //bit[14,15]:Channel selection }reg11; //Define a reg11 variable,The advantage of not declaring a struct is to ensure that variables are unique int main() { reg11.en =1; //bit8=1 --> 256 printf("1st:reg11=%d\n",reg11); //Print 256 reg11.en =5; //5(b'101) Keep low 1 bit: b'1 printf("2st:reg11=%d\n",reg11); //Print 256 reg11.en =6; //5(b'110) Keep low 1 bit: b'0 printf("3st:reg11=%d\n",reg11); //Print 0 return 0; }
Print:
4. Note that the default minimum length of a structure using a bit field is int (4 bytes). If it exceeds 4 bytes (32 bits), it will be 64 bits
Example:
#include <stdio.h> struct { unsigned a:4; unsigned b:2; unsigned c:1; }reg1; //The total length of bit field is only 7 bits struct reg{ unsigned a:4; unsigned b:2; unsigned c:32; }reg2; int main() { printf("%d\n",sizeof(reg1)); printf("%d\n",sizeof(reg2)); return 0; }
Print:
5. If a register has only 8 bits (1 byte), how to use bit field processing?
By using Union Union, each field can share a piece of memory. By reading and writing char variable in union structure, we can
Example:
#include <stdio.h> typedef union{ unsigned char val; struct { unsigned a:4; unsigned b:1; unsigned c:2; unsigned d:1; }bit; }reg11; //Use typedef ,Tell compiler,reg11 Is a declaration type int main() { reg11 reg; printf("sizeof=%d\n",sizeof(reg.val)); reg.val=0; reg.bit.b = 1; //bit[4]=1 printf("val = %d\n",reg.val); return 0; }
Print: