Essential C Language Knowledge for Beginners

Click the blue text
Essential C Language Knowledge for Beginners
Follow us

Due to changes in WeChat public account push rules, please click “See” and add “Star” to get exciting technical shares immediately

Source from the internet, please delete if infringing

C language is essential foundational knowledge in microcontroller development. This article lists some common basic knowledge of C language in STM32 learning, hoping to be helpful to everyone.

01

Bit Manipulation
First, we will explain several bit operators, then discuss techniques for using bit manipulation. The C language supports the following six operations:
Essential C Language Knowledge for Beginners
(Six Bit Operations)
Next, we will focus on some practical techniques of bit manipulation in microcontroller development.
1.1 Setting Specific Bits Without Changing Others
This scenario is often used in microcontroller development. The method is to first clear the bits that need to be set using the & operator, then use the | operator to set the values.
For example, to change the state of GPIOA, I can first clear the value of the register:
Essential C Language Knowledge for Beginners
Then perform the | operation with the value to be set:
Essential C Language Knowledge for Beginners
1.2 Shift Operations Improve Code Readability
Shift operations are very important in microcontroller development. Below is a line of code from the delay_init function:
SysTick->CTRL |= 1 << 1;
This operation sets the 1st bit (starting from 0) of the CTRL register to 1. Why use a left shift instead of directly setting a fixed value?
Actually, this is to improve code readability and reusability. This line of code clearly indicates that the 1st bit is set to 1. If written as:
SysTick->CTRL |= 0X0002;
This can achieve the same effect, but is less readable and more cumbersome to modify.
1.3 Bitwise NOT Operation Techniques
Bitwise NOT is often used when setting registers, commonly used to clear one or several bits. Below is a line of code from the delay_us function:
SysTick->CTRL &= ~(1 << 0);    /* Turn off SYSTICK */
This code can be interpreted as:only setting the 0th bit (least significant bit) of the CTRL register to 0, while keeping the values of other bits unchanged.
Similarly, without using bitwise NOT, we could write the code as:
SysTick->CTRL &= 0XFFFFFFFE;        /* Turn off SYSTICK */
It is evident that the former has much better readability and maintainability than the latter.
1.4 Bitwise XOR Operation Techniques
This function is very suitable for toggling a specific bit, a common application scenario is controlling LED blinking, as follows:
GPIOB->ODR ^= 1 << 5;
Executing this code will toggle the output state of PB5 once. If our LED is connected to PB5, we will see the LED blinking.

02

#define Macro Definitions
#define is a preprocessor command in C language used for macro definitions (which define constants) and can improve the readability of source code, providing convenience for programming. The common format is:
Essential C Language Knowledge for Beginners
“Identifier” is the name of the defined macro. “String” can be a constant, expression, format string, etc. For example:
Essential C Language Knowledge for Beginners
Defines the value of identifier HSE_VALUE as 8000000, where the U after the number indicates unsigned.As for other knowledge about #define macro definitions, such as macro definitions with parameters, I won’t elaborate here.

03

#ifdef Conditional Compilation
During microcontroller program development, it is common to encounter a situation where a group of statements is compiled when a certain condition is met, and another group of statements is compiled when the condition is not met.
The most common form of conditional compilation command is:
#ifdef Identifier    Segment1#else    Segment2#endif
Its function is: when the identifier has been defined (generally defined by the #define command), compile segment1, otherwise compile segment2.
The #else part can also be omitted, i.e.:
  #ifdef    Segment1    #endif
Conditional compilation is widely used in the HAL library. In the stm32mp1xx_hal_conf.h header file, you often see such statements:
   #if !defined  (HSE_VALUE)      #define HSE_VALUE            24000000U    #endif
If the HSE_VALUE macro is not defined, define the HSE_VALUE macro and set its value to 24000000U. Conditional compilation is also fundamental knowledge of C language.
It is worth mentioning that the U in 24000000U indicates an unsigned integer. Commonly, UL indicates an unsigned long integer, and F indicates a floating-point type.
With the U added, the system will not perform type checking during compilation, directly assigning the value to the corresponding memory as an unsigned. If it exceeds the defined variable’s range, it will truncate.

04

extern Variable Declaration
In C language, extern can be placed before a variable or function to indicate that the variable or function is defined in another file, prompting the compiler to look for its definition in other modules when encountering this variable and function.
It should be noted that extern declared variables can be declared multiple times, but defined only once. In our code, you will see statements like:
extern uint16_t g_usart_rx_sta;
This statement declares that the variable g_usart_rx_sta has been defined in another file and is used here.
Therefore, you can definitely find a statement defining the variable somewhere:
 uint16_t g_usart_rx_sta;
The use of extern is relatively simple but frequently used, and needs to be mastered.

05

typedef Type Alias
typedef is used to create a new name for an existing type, or type alias, to simplify variable definitions. The most common use of typedef in the HAL library is to define type aliases for structures and enumerations.
    struct _GPIO    {        __IO uint32_t CRL;        __IO uint32_t CRH;        …    };
This defines a structure GPIO, so we define the structure variable as:
struct  _GPIO  gpiox;       /* Define structure variable gpiox */
However, this is cumbersome, as there are many such structure variables to define in the HAL library.
Here we can define an alias for the structure as GPIO_TypeDef, so we can define structure variables elsewhere using the alias GPIO_TypeDef as follows:
    typedef struct    {            __IO uint32_t CRL;            __IO uint32_t CRH;            …    } GPIO_TypeDef;
Typedef creates an alias for the structure GPIO_TypeDef, allowing us to define structure variables using GPIO_TypeDef:GPIO_TypeDef gpiox;
Here, GPIO_TypeDef serves the same purpose as struct _GPIO, but is much more convenient to use.
END

If you are over 18 years old and find learning [C Language] too difficult? Want to try other programming languages, then I recommend you learn Python. Currently, there is a limited-time free course for beginners in Python worth 499 yuan, limited to 10 places!





▲ Scan the QR code - Get it for free








Essential C Language Knowledge for Beginners
Click to read the original text to learn more

Leave a Comment