1. Consortium
Previous articles< Combination of enumeration and structure >As mentioned in the article, the structure is like packaging, encapsulating some variables with common characteristics inside. A structure is a construction type or complex type that can contain multiple members of different types. In C language, there is another syntax very similar to structure, which is called Union (also called common body in some places).
Examples of consortium are as follows
union data{ char n; char ch; char f; }; union data a, b, c;
The difference between a structure and a consortium is that each member of the structure will occupy different memory and have no influence on each other; All members of the consortium occupy the same memory. Modifying one member will affect all other members.
The memory occupied by the structure is greater than or equal to the sum of the memory occupied by all members (there is a byte alignment problem, which will not be discussed in depth here).
The memory occupied by the consortium is equal to the memory occupied by the longest member. If you assign a value to a new member in a consortium, the value of the original member will be overwritten.
//Consortium definition above char data; a.n = 0x0A;//Although only member variables have been modified n,however ch and f Variables will be changed data = a.f;//that data The value of will be changed to 0 x0A
2. Application of consortium
The consortium is still very few in the general programming application, and more in the single-chip microcomputer programming, as shown in the previous article< Combination of enumeration and structure >Combining enumeration with structure, the following example briefly illustrates the application of the lower association in structure (in my daily development, the association is generally used with structure).
A concept is involved in the application of display screen. A pixel on the display screen (full-color) is composed of three colors: Red, Green and Blue. In 888 mode, each pixel is composed of 8 bit s. At this time, in order to be a pixel, a structure needs to be used, which also corresponds to the previous article. The structure is like packaging, Encapsulate some variables with common characteristics inside.
typedef struct{ uint8_t Red; uint8_t Green; uint8_t Blue; uint32_t Pix_Value; }LCD_Pixvalue_S;
The above way of writing is very clear and easy to access. You can access the whole pixel alone or a certain color of the pixel. One problem is that I need to give pix again when I operate the red pixel_ Value member assignment, as follows
LCD_Pixvalue_S LCD_Pixvalue; LCD_Pixvalue.Red = 0x12; LCD_Pixvalue.Pix_Value = LCD_Pixvalue.Red<<16 | LCD_Pixvalue.Red<<8 |LCD_Pixvalue.Blue;
One more sentence of code is required, and the memory consumption is also large. Of course, directly using the following method will not occupy more memory, but it is inconvenient to access.
typedef struct{ uint32_t Pix_Value; }LCD_Pixvalue_S;
Then at this time, using the combination of consortium and structure can not occupy more memory and access is very convenient.
typedef union{ struct{ uint8_t Red; uint8_t Green; uint8_t Blue; }Pix; uint32_t Pix_Value; }LCD_Pixvalue_S;
Then you can operate as follows
LCD_Pixvalue_S LCD_Pixvalue; uint32_t data; LCD_Pixvalue.Pix_Value = 0x0012FF00; LCD_Pixvalue.Pix.Red = 0x25;//Modify red separately data = LCD_Pixvalue.Pix_Value;//data The value of is 0 x0012FF25
Of course, you can also write the definition of structure outside, which can be used in other places, as follows
typedef struct{ uint8_t Red; uint8_t Green; uint8_t Blue; }Pix_s; typedef union{ Pix_s Pix; uint32_t Pix_Value; }LCD_Pixvalue_S;
For the problem of memory occupation, the above definition method defines an LCD_ Pixvalue_ Variables of type s occupy 4 bytes. An example is shown below
3. Application of consortium in serial port development
The above example is the application of consortium in LCD application. This is because a pixel of LCD is composed of red, green and blue, so it is very convenient to use consortium. In the development of single chip microcomputer project, the analysis of serial port protocol can also be used to the consortium, which is very convenient.
In the private user-defined protocol, it is very convenient to reasonably define the protocol and use the consortium code. The following examples do not talk about the frame header and tail, but the application of consortium in protocol analysis.
An example of serial port protocol is as follows
Then the code can be written as follows
typedef union{ struct{ uint32_t cmdlen; uint8_t cmd; uint8_t cmdbuf[7]; uint16_t crc16; }unit; uint8_t buffer[14]; }uart_buffer_s; uart_buffer_s uart_buffer; int main(void) { uint8_t len; len = 0; uart_buffer.buffer[len++] = 0x12; uart_buffer.buffer[len++] = 0x34; uart_buffer.buffer[len++] = 0x56; uart_buffer.buffer[len++] = 0x78; uart_buffer.buffer[len++] = 0xAA; for(int i=0;i<7;i++) { uart_buffer.buffer[len++] = i; } uart_buffer.buffer[len++] = 0x11; uart_buffer.buffer[len++] = 0x22; while (1); }
The results of the operation are as follows
As you can see, we're just going to UART_ buffer. The buffer fills in data and simulates the serial port to receive data. After receiving, it will automatically parse out our customized cmdlen, cmd, cmdbuf fer and crc16. It should be noted here that the 16 bit and 32-bit data types are small end mode. For the small end mode, please see the previous article< Memory allocation of C language in STM32 >, this is very convenient.
!!! But!!! Pay attention to the problem of byte alignment. For example, if the above cmdbuf is modified to 8 bytes, there will be a problem, as shown below
There will be problems with crc16. This is the problem of byte alignment. Students who don't understand Baidu by themselves. We won't focus on it here.
In addition to the Union used in the above custom protocol parsing, it can also solve the problem of reading floating-point floats. Floats occupy 4 bytes. What if the 4 bytes received from the serial port are converted into floats? The consortium can solve this problem
In the following example code, we know that the hexadecimal representation of floating point number 231.5 is 0x43678000.
typedef union{ float data; uint8_t buffer[4]; }uart_buffer_s; uart_buffer_s uart_buffer; int main(void) { uint8_t len; len = 0; uart_buffer.buffer[len++] = 0x00; uart_buffer.buffer[len++] = 0x80; uart_buffer.buffer[len++] = 0x67; uart_buffer.buffer[len++] = 0x43; while (1); }
give the result as follows
It can be seen that we simulate the receipt of 4 bytes from the serial port. Using the consortium, we can automatically convert it to float type without writing additional code. Of course, this conversion is also a small end mode. Please see the article for a detailed explanation of the small end mode< Memory allocation of C language in STM32>.