Introduction to STM32 (2)

Introduction to STM32 (2)

1. New construction

Insert picture description here

2. The relationship between library development and register development

The firmware library is a collection of functions. The function of the firmware library function is to directly deal with registers and provide an interface (API) for user function calls. In the development of 51, what we often do is to directly manipulate the registers. For example, to control the state of some IO ports, we directly manipulate the registers:

P0=0x11;

In the development of STM32, we can also manipulate registers:

GPIOx->BRR = 0x0011;

This method is certainly possible, but the disadvantage of this method is that you need to master the usage of each register so that you can use STM32 correctly. For an MCU of the STM32 level, it is easier to remember hundreds of registers. So ST (STMicroelectronics) launched the official firmware library. The firmware library encapsulates the low-level operations of these registers and provides a set of interfaces (API) for developers to call. In most cases, you don’t need to know which one is operating. Register, you only need to know which functions to call. For example, the above control BRR register realizes level control, the official library encapsulates a function:

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin){
    
      
38GPIOx->BRR = GPIO_Pin;
}

At that time, you don't need to directly manipulate the BRR register, you just need to know how to use the GPIO_ResetBits() function. After you have a certain understanding of the working principle of peripherals, you can look at the firmware library functions. Basically, the function name can tell you what the function of this function is and how to use it.

Three, STM32 official library

There are two directories under the Libraries folder, CMSIS and STM32F10x_StdPeriph_Driver. These two directories contain all the subfolders and files of the firmware library core. Among them are the startup files under the CMSIS directory, and STM32F10x_StdPeriph_Driver puts the source files of the STM32 firmware library. The inc directory under the source file directory stores the stm32f10x_xxx.h header file, no need to change. Below the src directory is the firmware library source file in stm32f10x_xxx.c format. Each .c file corresponds to a corresponding .h file.
The file here is also the core file of the firmware library, and each peripheral corresponds to a set of files. The files in the Libraries folder will be used when we build the project. There are two folders under the Project folder. As the name implies, ST official firmware example source code stored under the STM32F10x_StdPeriph_Examples folder, in the future development process, you can refer to modify this official example to quickly drive your own peripherals, many development board examples refer to the official provided The source code of the routines, these source codes are very important for future learning. The project template is stored under the STM32F10x_StdPeriph_Template folder

Below we will focus on several important files under the Libraries directory. The core_cm3.c and core_cm3.h files are located under the \Libraries\CMSIS\CM3\CoreSupport directory. This is the CMSIS core file, which provides access to the M3 core interface. This is provided by ARM and is the same for all CM3 core chips. You never need to modify this file.

There are three files under this directory: system_stm32f10x.c, system_stm32f10x.h and stm32f10x.h files. The function of system_stm32f10x.c and the corresponding header file system_stm32f10x.h is to set the system and bus clock. There is a very important SystemInit() function, which will be called when our system starts to set the system The entire clock system.

Four, SYSTEM folder introduction

The SYSTEM folder contains three folders: delay, sys, and usart. Respectively include delay.c, sys.c, usart.c and its header files delay.h, sys.h, usart.h.

4.1 Introduction to the delay folder code

The delay folder contains two files, delay.c and delay.h, which are used to implement the delay function of the system, which contains 3 functions

void delay_init(u8 SYSCLK);
void delay_ms(u16 nms);
void delay_us(u32 nus);

4.2 Introduction to sys folder code

The sys folder contains two files, sys.c and sys.h. Define the STM32 IO port input read macro definition and output macro definition in sys.h. Only one interrupt group function is defined in sys.c

== IO port bit operation realization ==
This part of the code is in the sys.h file, which realizes the bit operation of each IO port of STM32, including reading and outputting. Of course, before calling these functions, you must first enable the IO port clock and define the IO port function. This part only reads and controls the input and output of the IO port.

To put it simply, bit-banding operation is to expand each bit into a 32-bit word. When these words are accessed, the purpose of accessing the bits is achieved. For example, if the BSRR register has 32 bits, it can be mapped to 32 addresses. Above, we visit these 32 addresses to achieve the purpose of accessing 32 bits. In this way, we can write 1 to a certain address to achieve the purpose of writing 1 to the corresponding bit, and write 0 to a certain address to achieve the purpose of writing 0 to the corresponding bit.
Insert picture description here
For the above figure, we write 1 to Address0 address, then we can achieve the purpose of assigning 1 to Bit0 of the register. We don't want to talk too complicated here, because the bit-band operation may only be used for the input and output of the IO port in actual development. It is more convenient, and other operations are rarely used in daily development. Let's look at the definition of bit band operation in sys.h.

#define BITBAND(addr,bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)    *((volatile unsigned long    *)(addr)) 
#define BIT_ADDR(addr,bitnum)      MEM_ADDR(BITBAND(addr,bitnum)) //IO口地址映射
#define GPIOA_ODR_Addr        (GPIOA_BASE+12) //0x4001080C 
#define GPIOB_ODR_Addr        (GPIOB_BASE+12) //0x40010C0C 
#define GPIOC_ODR_Addr        (GPIOC_BASE+12) //0x4001100C 
#define GPIOD_ODR_Addr        (GPIOD_BASE+12) //0x4001140C 
#define GPIOE_ODR_Addr        (GPIOE_BASE+12) //0x4001180C 
#define GPIOF_ODR_Addr        (GPIOF_BASE+12) //0x40011A0C       
#define GPIOG_ODR_Addr        (GPIOG_BASE+12) //0x40011E0C   
#define GPIOA_IDR_Addr        (GPIOA_BASE+8) //0x40010808 
#define GPIOB_IDR_Addr        (GPIOB_BASE+8) //0x40010C08 
#define GPIOC_IDR_Addr        (GPIOC_BASE+8) //0x40011008 
#define GPIOD_IDR_Addr        (GPIOD_BASE+8) //0x40011408 
#define GPIOE_IDR_Addr        (GPIOE_BASE+8) //0x40011808 
#define GPIOF_IDR_Addr        (GPIOF_BASE+8) //0x40011A08 
#define GPIOG_IDR_Addr        (GPIOG_BASE+8) //0x40011E08   //IO口操作,只对单一的IO口!//确保n的值小于16!
#define PAout(n)      BIT_ADDR(GPIOA_ODR_Addr,n)    //输出
#define PAin(n)        BIT_ADDR(GPIOA_IDR_Addr,n)    //输入
#define PBout(n)      BIT_ADDR(GPIOB_ODR_Addr,n)    //输出
#define PBin(n)        BIT_ADDR(GPIOB_IDR_Addr,n)    //输入
#define PCout(n)      BIT_ADDR(GPIOC_ODR_Addr,n)    //输出
#define PCin(n)        BIT_ADDR(GPIOC_IDR_Addr,n)    //输入
#define PDout(n)      BIT_ADDR(GPIOD_ODR_Addr,n)    //输出
#define PDin(n)        BIT_ADDR(GPIOD_IDR_Addr,n)    //输入
#define PEout(n)      BIT_ADDR(GPIOE_ODR_Addr,n)    //输出
#define PEin(n)        BIT_ADDR(GPIOE_IDR_Addr,n)    //输入
#define PFout(n)      BIT_ADDR(GPIOF_ODR_Addr,n)    //输出
#define PFin(n)        BIT_ADDR(GPIOF_IDR_Addr,n)    //输入
#define PGout(n)      BIT_ADDR(GPIOG_ODR_Addr,n)    //输出
#define PGin(n)        BIT_ADDR(GPIOG_IDR_Addr,n)    //输入

With the above code, we can operate the IO port of STM32 like 51/AVR. For example, if I want the seventh IO port of PORTA to output 1, I can use PAout(6)=1; I want to judge whether the 15th bit of PORTA is equal to 1, then I can use if (PAin(14)==1)...; that's it.

4.3 Introduction to usart folder

The usart folder contains two files, usart.c and usart.h. These two files are used for serial port initialization and interrupt reception. This is only for serial port 1. For example, if you want to use serial port 2 or other serial ports, you only need to modify the code slightly. There are two functions in usart.c, one is void USART1_IRQHandler(void); the other is void uart_init(u32 bound); there is also a piece of support code for serial port printf, if it is removed, it will cause printf to be unusable, although the software Compilation will not report an error, but STM32 cannot be started on the hardware. Do not modify this code.

Guess you like

Origin blog.csdn.net/weixin_44026026/article/details/113198053