catalogue
1, Address mapping and register mapping principle of STM32F103 series chips
2, Understand the three steps of GPIO port initialization settings
1, Address mapping and register mapping principle of STM32F103 series chips
1. Address mapping
In the STM32 firmware library, there is a header file called stm32f10x.h, which defines the mapping of registers. Some codes are as follows:
Peripheral base address PERIPH_BASE:
#define PERIPH_BASE ((uint32_t)0x40000000)
Bus base address, add offset to peripheral base address:
#define APB1PERIPH_BASE PERIPH_BASE #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
GPIO peripheral base address, add offset to APB2 bus base address:
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) #define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) #define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) #define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) #define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) #define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00) #define GPIOG_BASE (APB2PERIPH_BASE + 0x2000)
Define the GPIO peripheral structure. Because the structure members are continuous in memory, this form is very similar to the register group, so the structure can be used to manage the registers well:
typedef struct { __IO uint32_t CRL; __IO uint32_t CRH; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; } GPIO_TypeDef;
Define the GPIOA structure pointer. Because defining the GPIO peripheral structure alone cannot determine its memory address, bind it to the GPIOA peripheral base address with a pointer:
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
Compared with register access methods, mapping access is obviously more intuitive:
//Direct address access *(unsigned int *)(0x4001_0800)|= 0x0001; //Map access GPIOA->CRL |= 0x0001;
2. Register mapping
Register mapping is mainly for Block2. This mapping is different from the address allocation operation of memory mapping, but the process of naming memory units with specific functions in the program. Each memory unit is four bytes, called registers. For example, the GPIOA peripheral has a register with an address range of 0x4001_0800~0x4001_0803, this register is used to configure the working mode of some ports of GPIOA, so it is mapped to GPIOA_CRL. It can be seen that this mapping facilitates the access to the register, because it is very painful to check the address range every time you access the register.
How to implement this mapping? In gpioa_ Taking CRL as an example, its mapping address = total peripheral base address (block base address) + offset of bus from total peripheral base address + offset of specific peripheral base address from bus base address + offset of register from external base address.
The total base address of the peripheral is exactly the starting address 0x4000 of Block2_ 0000;
GPIO belongs to APB2 bus peripherals. Therefore, refer to the chip manual as shown in the figure below. In fact, we can directly obtain the APB2 start address and GPIOA start address. However, this is generally not done in the program, but the hierarchical relationship is represented by offset. It can be calculated from the figure that the offset of the bus relative to the total base address of the peripheral is 0x1_0000, the offset of GPIOA relative to APB2 base address is 0x800.
Then check the register group of GPIO, as shown in the figure below. It can be obtained that the offset of CRL register relative to GPIO base address is 0x00. To sum up, gpioa_ The base address of CRL is 0x4000_0000+0x1_0000+0x800+0x00.
2, Understand the three steps of GPIO port initialization settings
There are 7 groups of IO ports in the development board of STM32F103ZE, and each group has 16 IO ports, that is, there are 112 IO ports in this board, which are GPIOA~GPIOG respectively. Each I/O port bit can be programmed freely, but the I/O port register must be accessed by 32-bit bytes, and half word or single byte access is not allowed.
There are eight main working modes of GPIO: four input modes and four output modes: input floating, input pull-up, input pull-down and analog input; The output mode is open drain output, open drain multiplex output, push-pull output and push-pull multiplex output.
(1)GPIO_Mode_AIN analog input (apply ADC analog input or save power under low power consumption)
(2)GPIO_Mode_IN_FLOATING floating input (floating is floating in mid air, which can be pulled up or down by other objects, and can be used for key input)
(3)GPIO_Mode_IPD pull-down input (IO internal pull-down resistance input)
(4)GPIO_Mode_IPU pull-up input (IO internal pull-up resistance input)
(5)GPIO_Mode_Out_OD open drain output (open drain output: the output end is equivalent to the collector of the triode. To get the high-level state, you need to pull up the resistance)
(6)GPIO_Mode_Out_PP push-pull output (push-pull means push and pull, and the levels are determined without pull-up and pull-down. IO output 0-GND, IO output 1-VCC, and the read input value is unknown)
(7)GPIO_Mode_AF_OD multiplex open drain output (on-chip and off-chip functions (SCL and SDA of I2C))
(8)GPIO_Mode_AF_PP multiplex push-pull output (on-chip and off-chip functions (TX1,MOSI,MISO.SCK.SS))
GPIO initialization steps
Step 1: enable the clock of GPIOx port
Step 2: indicate which bit of GPIOx port, the speed, size and mode of this bit.
Step 3: call the GPIOx port initialization function to initialize.
Step 4: call GPIO setbits function to set corresponding.
Examples are as follows
☞ the initialization of a single GPIO port is as follows
GPIO_InitTypeDef GPIO_InitStructure;
Step 1: enable the clock of GPIOA:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
Step 2: set GPIOA parameters: output, OR input, working mode and port turnover rate
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_6| GPIO_Pin_7| GPIO_Pin_8; // Set pin to operate
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // Set to push-pull output
GPIO_ InitStructure.GPIO_ Speed = GPIO_ Speed_ 50MHz; // The speed of IO port is 50MHz
Step 3: call the GPIOA port initialization function to initialize.
GPIO_ Init(GPIOA, &GPIO_InitStructure); // Initialize gpioa according to the set parameters
Step 4: call GPIO setbits function to set corresponding.
GPIO_SetBits(GPIOA,GPIO_Pin_0); // Output high
The initialization of multiple GPIO ports is as follows
GPIO_InitTypeDef GPIO_InitStructure;
Step 1: enable the clock of GPIOA and GPIOE:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
Step 2: set gpioa and gpioe parameters: output OR input, working mode and port turnover rate
Step 3: call the GPIOA port initialization function to initialize.
Step 4: call GPIO setbits function to set corresponding.
▶ Merge the second, third and fourth steps to set GPIOA and GPIOE respectively
Set GPIOA first
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // Fourth port, PA4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // Set to push-pull output
GPIO_ InitStructure.GPIO_ Speed = GPIO_ Speed_ 50MHz; // The speed of IO port is 50MHz
GPIO_ Init(GPIOA,&GPIO-InitST); // Initialize gpioa according to the set parameters
GPIO_SetBits(GPIOA,GPIO_Pin_4); // Output high
Then set GPIOE
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // Third port, PE3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // Set to push-pull output
GPIO_ InitStructure.GPIO_ Speed = GPIO_ Speed_ 50MHz; // The speed of IO port is 50MHz
GPIO_ Init(GPIOE,&GPIO-InitST); // Initialize gpioe according to the set parameters
GPIO_SetBits(GPIOE,GPIO_Pin_3); // Output high
3, Turn on the LED water lamp
1. Code
1.c
#include "stm32f10x.h" //----------------APB2??????? --------------------- #define RCC_APB2ENR *((unsigned volatile int*)0x40021018) //----------------GPIOA????? ----------------------- #define GPIOA_CRL *((unsigned volatile int*)0x40010800) #define GPIOA_ODR *((unsigned volatile int*)0x4001080C) //----------------GPIOB????? ----------------------- #define GPIOB_CRL *((unsigned volatile int*)0x40010C00) #define GPIOB_ODR *((unsigned volatile int*)0x40010C0C) //----------------GPIOC????? ----------------------- #define GPIOC_CRH *((unsigned volatile int*)0x40011004) #define GPIOC_ODR *((unsigned volatile int*)0x4001100C) extern void led(void); //???? void Delay() { u32 i=0; for(;i<5000000;i++); } //?1 void led1() { GPIOA_ODR|=1<<4; //PA4??? Delay(); GPIOA_ODR&=~(1<<4);//PA4???,??????? Delay(); } //?2 void led2() { GPIOB_ODR|=1<<5; //PB4??? Delay(); GPIOB_ODR&=~(1<<5);//PB4???,??????? Delay(); } //?3 void led3() { GPIOC_ODR|=1<<14; //PC14??? Delay(); GPIOC_ODR&=~(1<<14);//PC14???,??????? Delay(); } int main(void) { led(); RCC_APB2ENR|=1<<2|1<<3|1<<4; //APB2-GPIOA?GPIOB?GPIOC?????? GPIOA_CRL&=0xFFF0FFFF; //??? ?? GPIOA_CRL|=0x00020000; //PA4???? GPIOA_ODR&=~(1<<4); //??????? GPIOB_CRL&=0xFF0FFFFF; //??? ?? GPIOB_CRL|=0x00200000; //PB5???? GPIOB_ODR&=~(1<<5); //??????? GPIOC_CRH&=0xF0FFFFFF; //??? ?? GPIOC_CRH|=0x02000000; //PC14???? GPIOC_ODR&=~(1<<14); //??????? while(1){ led1(); led2(); led3(); } }
2.s
AREA MYDATA, DATA AREA MYCODE, CODE ENTRY EXPORT led led ;??A,B,C ldr r0, =0x40021018 ldr r1, =0x0000001c str r1, [r0] ;????A4 ldr r0, =0x40010800 ldr r1, [r0] bic r1, r1, #0x000f0000 orr r1, r1, #0x00010000 str r1, [r0] ;????B5 ldr r0, =0x40010c00 ldr r1, [r0] bic r1, r1, #0x00f00000 orr r1, r1, #0x00100000 str r1, [r0] ;????C14 ldr r0, =0x40011004 ldr r1, [r0] bic r1, r1, #0x0f000000 orr r1, r1, #0x01000000 str r1, [r0] ;??A4?? ldr r0, =0x4001080c ldr r1, =0x00000010 str r1, [r0] ldr r0, =5000000;?? ldr r1, =0 ;???? blink add r1, r1, #1 cmp r1, r0 blt blink ;??A4? ldr r1, =0x4001080c ldr r2, [r1] eor r2, r2, #0x00000010 str r2, [r1] ;??B5? ldr r1, =0x40010c0c ldr r2, [r1] eor r2, r2, #0x00000020 str r2, [r1] ldr r1, =0 blink1 add r1, r1, #1 cmp r1, r0 blt blink1 ;??B5? ldr r1, =0x40010c0c ldr r2, [r1] eor r2, r2, #0x00000020 str r2, [r1] ;??C14? ldr r1, =0x4001100c ldr r2, [r1] eor r2, r2, #0x00004000 str r2, [r1] ldr r1, =0 blink2 add r1, r1, #1 cmp r1, r0 blt blink2 ;??C14? ldr r1, =0x4001100c ldr r2, [r1] eor r2, r2, #0x00004000 str r2, [r1] ;??A4? ldr r1, =0x4001080c ldr r2, [r1] eor r2, r2, #0x00000010 str r2, [r1] ldr r1, =0 b blink END
2. Execution waveform
3. Results
12346876453_ Beep beep beep_ bilibili
4, References
STM32 memory mapping and register mapping - KenSporger - blog Park (cnblogs.com)
STM32 getting started - GPIO initialization steps_ Love learning big meow blog - CSDN blog
STM32F103 register mode turns on the LED water flow lamp_ Parallel leaf blog - CSDN blog