Summary of C Language Basics for STM32 Microcontrollers

C language is essential foundational knowledge in microcontroller development. This article lists some common C language basics encountered while learning STM32.

1 Bit Manipulation

First, we will explain several bitwise operators, followed by tips for using bitwise operations. The C language supports the following six types of bitwise operations:
Summary of C Language Basics for STM32 Microcontrollers
Next, we will focus on some practical tips for using bitwise operations in microcontroller development.
1.1 Setting Bits Without Changing Other Bit Values
This scenario is frequently used in microcontroller development. The method is to first clear the bits that need to be set using the & operator, and then set them using the | operator.
For example, to change the state of GPIOA, we can first clear the register value:
Summary of C Language Basics for STM32 Microcontrollers
Then perform a | operation with the value to be set:
Summary of C Language Basics for STM32 Microcontrollers
1.2 Shift Operations to 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 first bit (starting from 0) of the CTRL register to 1. Why use a left shift instead of directly setting a fixed value?
This is to improve code readability and reusability. This line of code clearly indicates that the first bit is set to 1. If written as:
SysTick->CTRL |= 0X0002;
This achieves the same effect, but is less readable and more cumbersome to modify.
1.3 Bitwise NOT Operation Tips
The bitwise NOT operation is often used when setting registers, commonly used to clear one or more bits.Below is a line of code from the delay_us function:
SysTick->CTRL &= ~(1 << 0);    /* Disable SYSTICK */
This code can be interpreted as: setting only the 0th bit (least significant bit) of the CTRL register to 0, while keeping the values of other bits unchanged.
Similarly, if we do not use the bitwise NOT and write the code as:
SysTick->CTRL &= 0XFFFFFFFE;        /* Disable SYSTICK */
It is evident that the former is much better in terms of readability and maintainability.
1.4 Bitwise XOR Operation Tips
This function is very suitable for toggling a bit, a common application scenario is controlling an LED blink, 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.

2 Define Macro Definitions

Define is a preprocessor command in C language used for macro definitions (defining constants), which can improve the readability of source code and facilitate programming. The common format is:
Summary of C Language Basics for STM32 Microcontrollers
“Identifier” is the name of the defined macro.“String” can be a constant, expression, format string, etc.For example:
Summary of C Language Basics for STM32 Microcontrollers
Defining the identifier HSE_VALUE as 8000000, the U after the number indicates that it is unsigned.Other knowledge regarding define macro definitions, such as macro definitions with parameters, will not be discussed here.

3 Ifdef Conditional Compilation

During the microcontroller program development process, there often arises 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    Program Segment 1#else    Program Segment 2#endif
Its function is: when the identifier has been defined (usually defined using the #define command), compile program segment 1; otherwise, compile program segment 2.
The #else part can also be omitted, as follows:
  #ifdef    Program Segment 1    #endif
Conditional compilation is widely used in the HAL library, and you will often see such statements in the stm32mp1xx_hal_conf.h header file:
#if !defined  (HSE_VALUE)      #define HSE_VALUE       24000000U    #endif
If the HSE_VALUE macro is not defined, it defines the HSE_VALUE macro with a value of 24000000U. Conditional compilation is also a fundamental knowledge of C language.
It is worth mentioning that the U in 24000000U indicates an unsigned integer, and commonly UL represents an unsigned long integer, and F represents a floating-point type.
By adding U, the system will not perform type checking during compilation and will directly assign the value to the corresponding memory in the form of U. If it exceeds the defined variable’s range, it will be truncated.

4 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 it encounters this variable and function.
It is important to note that an extern declared variable can be declared multiple times, but it can only be defined once.In our code, you will see such statements:
extern uint16_t g_usart_rx_sta;
This statement declares that the variable g_usart_rx_sta has already been defined in another file and is used here.
Thus, you can find a statement defining the variable somewhere:
 uint16_t g_usart_rx_sta;
The use of extern is relatively simple but also frequently used, and it is essential to master it.

5 Typedef Type Alias

Typedef is used to create a new name for an existing type, or a type alias, to simplify variable definitions.Typedef is most commonly used in the HAL library 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 follows:
struct  _GPIO  gpiox;       /* Define structure variable gpiox */
However, this is quite cumbersome, as there are many such structure variables to define in the HAL library.
Here we can define an alias GPIO_TypeDef for the structure, allowing us to define structure variables using the alias GPIO_TypeDef elsewhere, as follows:
typedef struct    {            __IO uint32_t CRL;            __IO uint32_t CRH;            …    } GPIO_TypeDef;
Typedef creates an alias GPIO_TypeDef for the structure, allowing us to define structure variables using GPIO_TypeDef:
GPIO_TypeDef gpiox;
Here, GPIO_TypeDef serves the same purpose as struct _GPIO, but using GPIO_TypeDef is much more convenient.
Article adapted from: STM32 Embedded Development
(End)

More exciting content:

Yan Shi│Reflections and Suggestions on the “Dilemma” of Young Teachers in Universities

Academician Zheng Weimin: Why Computer Majors Have Become Popular Among Candidates

【Directory】”Computer Education” Issue 7, 2022

【Directory】”Computer Education” Issue 6, 2022

【Directory】”Computer Education” Issue 5, 2022

【Directory】”Computer Education” Issue 4, 2022

【Directory】”Computer Education” Issue 3, 2022

【Directory】”Computer Education” Issue 2, 2022

【Directory】”Computer Education” Issue 1, 2022

【Editorial Board Message】Professor Li Xiaoming from Peking University: Thoughts from the “Year of Classroom Teaching Improvement”…

Professor Chen Daoxu from Nanjing University: Which is more important, teaching students to ask questions or teaching students to answer questions?

【Yan Shi Series】: Trends in Computer Science Development and Their Impact on Computer Education

Professor Li Xiaoming from Peking University: From Interesting Mathematics to Interesting Algorithms to Interesting Programming—A Path for Non-Majors to Experience Computational Thinking?

Reflections on Several Issues in Building First-Class Computer Disciplines

Professor Zhan Dechen from Harbin Institute of Technology Answers 2000 Questions About AI

Professor Zhou Aoying, Vice President of East China Normal University: Accelerating the Advancement of Computer Science Education—An Interview with…

New Engineering and Big Data Professional Construction

Learning from Others—Compilation of Research Articles on Computer Education at Home and Abroad

Summary of C Language Basics for STM32 Microcontrollers

Summary of C Language Basics for STM32 Microcontrollers

Leave a Comment