Overview:
Describes how to use the C language to encapsulate the underlying registers
Content:
- Memory mapping
- Register and register Mappings
- C-Language Access register
- Memory mapping
Program memory, data memory, register, and I/O ports are arranged in the same order of 4 GB
In the address space
Memory Mapping:
The memory itself does not have address information, its address is assigned by the chip manufacturer or user, to the memory
The process of assigning an address is called a memory map, which is called a remap if another address is assigned.
Memory Area Division
ARM divides this 4GB memory space by an average of 8 blocks
The size of each chunk is 512MB, the capacity is very large, so the chip manufacturers in each block
To design their own features within the range, it is important to note that the larger the capacity of each area, the chip cost
The higher, so that we use the STM32 chip is only a part of it.
Of these 8 blocks, the 3 Block0, Block1 and Block2 are our most
of the heart. Because it contains the internal flash, RAM, and on-chip peripherals of the STM32 chip.
The
Block0 has a lot of function blocks inside, and we're introducing them from low to high order by address
.
0x0000 0000-0x0007 FFFF: Depending on the boot pin, the alias for Flash, system memory,
SRAM.
0x0008 0000-0x07ff FFFF: Reserved.
0x0800 0000-0x0807 FFFF: On-Chip Flash, the program we wrote is placed in this area
(512KB).
0x0808 0000-0x1fff efff: Reserved.
0X1FFF f000-0x1fff f7ff: System memory, which is stored in the St when the factory burned to write good
The ISP bootstrap program, the user cannot change. Use this part of the program to download the serial port.
0X1FFF f800-0x1fff f80f: Option byte for configuring read-write protection,
BOR level, software/hardware watchdog, and device reset in standby or stop mode. When the chip does not
After careful locking, we can start from RAM to modify this part of the corresponding register bit.
0X1FFF f810-0x1fff FFFF: Reserved.
(2) Block1 Internal Area function Division
Block1 is used for designing on-chip SRAM, and the Stm32f103zet6 SRAM we use is 64KB.
From the figure 5.1.1, we can see that there are several function blocks inside the BLOCK1, and we are from low to high by address.
The order is described in turn.
0x2000 0000-0x2000 Ffff:sram with a capacity of 64KB.
0x2001 0000-0x3fff FFFF: Reserved.
(3) Block2 Internal Area function Division
The Block2 is designed for on-chip peripherals, and the Block2 is divided into AHB depending on the peripheral bus speed.
and APB two parts, APB is divided into APB1 and APB2 bus. These can all be seen in Figure 5.1.1,
We introduce them sequentially from low to high.
0x4000 0000-0x4000 77FF:APB1 Bus peripherals.
0x4000 7800-0x4000 FFFF: Reserved.
0x4001 0000-0x4001 3FFF:APB2 Bus peripherals.
0x4001 4000-0x4001 7FFF: Reserved.
0x4001 8000-0x4002 33FF:AHB Bus peripherals.
0x4002 4400-0x5fff FFFF: Reserved.
Also included in the BLOCK3/4/5 is the FSMC extended area, which can be used to extend the external memory for 3 blocks.
such as Sram,norflash and Nandflash.
Register and register Mappings
Lock2 This area is designed for on-chip peripherals,
Since the CORTEX-M3 core is 32 bits, the internal memory is a four-byte unit, each
A unit corresponds to different functions, and when we control these units we can control the peripherals. Each single
The meta also corresponds to an address that we want to manipulate, which is accessed through the corresponding address. Because
STM32 peripherals are very numerous and complex, and if you have to write a large number of corresponding storage units per peripheral
Address, which is obviously cumbersome and extremely error-prone. So we'll take the function of each unit as
Name, give the inside access to an alias, this alias is the register we often say.
Then through C
Language pointers to manipulate these registers. So what is a register mapping? To an already assigned address.
The process of taking an alias for a memory cell with a specific function is called a register map.
Let's say we find the 0X4001 1010 Unit address, then we can check the relevant information
Solution to this unit has the GPIOC port position/reset function (as for this address how to find this feature we
The details are described later). Therefore, in order to better differentiate the function of this unit and to facilitate subsequent program development,
To give this unit an alias GPIOC_BSRR, then this GPIOC_BSRR is a register, and
This register address is 0x4001 1010. This process is the register mapping.
How to access the contents of the STM32 register:
We know that registers are some memory units with specific functions, so access to the STM32 register
This is the memory unit that operates STM32, which can be manipulated using pointers according to the characteristics of the C language pointer.
The STM32 memory unit. If we're going to let STM32 's Gpioc's No. 0 pin output Low, we
How to use C language to deal with?
Chip Sisu is divided into four bus, depending on the speed of the peripheral, different bus mounted different external
APB1 mounted low-speed peripherals, APB2 and AHB mounted high velocity peripherals. The lowest address of the corresponding bus I
Known as the base address of the bus, the bus base site is also the address of the first peripheral that is mounted on the bus.
The APB1 bus has the lowest address, so the on-chip peripherals start from this address, also known as the peripheral base address.
Peripheral Base Address
Many peripherals are hung on each bus, and these peripherals have their own range of addresses.
The first address of the XXX peripheral is the minimum address is the base address of xxx peripherals, also known as XXX boundary ground
Access. Refer to the STM32F1XX Chinese reference manual for the specific boundary address of the stm32f1xx peripherals.
Book "P28 page, in which there is a detailed introduction. Here we will use Gpio peripherals to explain the peripheral base address.
Other peripherals are equally analyzed.
The peripheral gpiox are hooked up to the APB2 bus, which belongs to the high-speed external
The base address of the APB2 bus is 0x4001 0000, so the address of the Gpioa relative APB2 bus is biased
The shift is 800.
(3) Peripheral Register Address
The registers for the XXX peripherals are distributed within the corresponding peripheral address range. Here we are outside the Gpio
For example, GPIO is a generic input-output port abbreviation, which can be controlled by software to control its input and output.
GPIO has a number of registers, each of which has a specific function. Each register is 32bit, accounting for four
Bytes, these registers are sequentially arranged in sequence on the base address of the peripheral. The registers are positioned in phase
Puzhong stm32f1xx Development Strategy
www.prechin.cn
39
The offset address of the base site of the peripheral is described. Here we take the GPIOC port as an example to illustrate the Gpio
What registers are there,
Here we will use the GPIOC_BSRR register to teach you how to see the stm32f1xx Chinese reference hand
Register in the register. If you want to learn more about the contents of the register, you can refer to the STM32F1XX
The corresponding Register Peripherals section of the Chinese reference manual.
First we need to open the STM32 Chinese reference manual and then find the Gpio Peripherals section, which will
There is a gpio register, just find the register we are looking for
A. Red Box 4 Indicates the name of the register we are looking for, the X table in register GPIOX_BSRR
shows the Stm32gpio port, the range is a-e, that is, in Gpioa, GPIOB and other ports have
this register.
B. The Red box 5 represents the offset value of the relative Gpiox address, for example, now we are using the
Gpioc peripheral, whose base address is 0x4001 1000, then this register GPIOX_BSRR address =0x4001
1000+0x10= 0X4001 1010. It is also a principle for other gpio peripherals.
C. Red boxes 6 and 7 represent the Register's bit table. Where 6 represents the register number because a
The register is 32bit, so the range is 0-31. 7 represents the permission for the corresponding bit, W: Write only, R: only
Read, RW: Readable and writable. This register bit permission is W, so only write, if try to read register,
is not guaranteed to read to its true content. Some register-bit permissions are read-only and are typically used to denote
STM32 a working state of a peripheral, automatically changed by the STM32 hardware by reading those register bits
To determine the working status of the peripheral.
D. The red Box 8 is the Register bit function description. This is also the most important part of the register description, which
The function of each bit of register is described in detail. For example, there are two register bits in this register, namely
BRy and Bsy, where the Y value represents the PIN number, which can be 0-15. such as BR0, BS0 for
Control the No. 0 pin of the Gpiox, if X represents GPIOC, that is the No. 0 pin of the control GPIOC,
And BR1, BS1 is the control GPIOC 1th pin.
Where the description of the Bry pin is "0: do not perform any operation on the corresponding ODRX bit; 1:
The corresponding ODRX bit is reset ". The "reset" here means that the bit is set to 0, while the "reset"
Bit "means that the bit is set to 1; the Odrx in the description is the register bit of another register, we only
When you need to know that the ODRX bit is 1, the corresponding pin x output is high, which is 0.
Pin output is low (readers of interest can query the description of the Register GPIOX_ODR
Solution). So, if you write "1" to BR0, then the No. 0 pin of Gpiox will output
"Low", but writes "0" to the BR0, but does not affect the ODR0 bit, so the pin power
Flat will not change. To output "high" on this pin, you need to write "1" to the "BS0" bit and send
The BSY and Bry are the opposite operation.
Using the C language Encapsulation Register:
Example 1: The No. 0 pin output of the control GPIOC port is a low level. First we need to know
The GPIOC port peripherals are hooked up on which bus, and then based on the bus base address and the offset address of itself
The base address of the GPIOC peripheral is obtained, and finally the base address of each register is obtained through this peripheral site.
(1) Bus and peripheral base address package
Puzhong stm32f1xx Development Strategy
www.prechin.cn
41
Based on the concept of a register, we can define the register using the macro definition in the C language. With
The body code is as follows:
Define the peripheral base address
#define PERIPH_BASE ((unsigned int) 0x40000000) 1)
Define APB2 Bus Base Address
#define APB2PERIPH_BASE (Periph_base + 0x00010000) 2)
Define GPIOC Peripheral Base Address
#define GPIOC_BASE (Ahb1periph_base + 0x0800) 3)
Define register base Address here, take GPIOC as an example
#define GPIOC_CRL * (unsigned int*) (gpioc_base+0x00) 4)
#define GPIOC_CRH * (unsigned int*) (gpioc_base+0x04)
#define GPIOC_IDR * (unsigned int*) (gpioc_base+0x08)
#define GPIOC_ODR * (unsigned int*) (gpioc_base+0x0c)
#define GPIOC_BSRR * (unsigned int*) (gpioc_base+0x10)
#define GPIOC_BRR * (unsigned int*) (gpioc_base+0x14)
#define GPIOC_LCKR * (unsigned int*) (gpioc_base+0x18)
In the above code we note the number below, which is briefly described below for its function:
1) Define the base address of the peripheral, which is also the base address of the Block2.
2) define the APB2 bus base address, because the first bus of Block2 is APB1, and APB2 total
The line address only needs to add the corresponding address offset.
3) Define the Gpio peripheral base address, because the GPIOC is hooked up on the APB2 bus, so find
The corresponding port address offset to know the GPIOC Port base address.
4) Define the Gpio peripheral register base address, where the GPIOC port is the example, because GPIOC_CRL
Is the first register of the GPIOC peripheral, so the base address is the GPIOC address, and the other register addresses only
You need to add a corresponding offset to the GPIOC base address.
We get the specific address of the register, then we can use the C language pointer to read and write. Cases
If we need to GPIOC0 output a low level or high level, you can use the following statement to operate.
Control GPIOC No. 0 pin output a low level
GPIOC_BSRR = (0x01<< (16+0));
Control GPIOC No. 0 pin output a high level
GPIOC_BSRR = (0x01<<0);
We know that the value of GPIOC_BSRR is the address of this register, but the compiler does not know that it is the ground
It as an immediate number, so we have to convert it to a (unsigned int *) pointer
Type before it can be manipulated, this is especially important. And then add a "*" to the front to take the finger.
Pin operation, which means that the content in the address is written, the read operation also uses "*" to take the pointer operation. Such as
Under
unsigned int temp;
Temp =GPIOC_IDR;
Keep the data in the register in the variable temp and be sure to define it when used with variables.
Register Encapsulation
We have already been able to operate the registers with the previous explanation, but there is a slight shortage because
STM32 's Gpio is more, we can't use a gpio to do a lot of the same definition as before.
Based on the characteristics of the GPIO registers, we know that both Gpioa and Gpiob have a set of functional phases
The same registers, such as GPIOA_ODR/GPIOB_ODR/GPIOC_ODR, and so on, they are just different addresses.
To make it easier to access registers, we introduce the structure of the C language to encapsulate the registers,
The body code is as follows:
typedef unsigned int uint32_t; /* Unsigned 32-bit variable */
typedef unsigned short int uint16_t; /* Unsigned 16-bit variable */
/* GPIO Register list */
typedef struct
{
uint32_t CRL; /*gpio Port configuration Low Register address offset: 0x00 */
uint32_t CRH; /*gpio port configuration High Register address offset: 0x04 */
uint32_t IDR; /*gpio Data Input Register address offset: 0x08 */
uint32_t ODR; /*gpio Data Output Register address offset: 0x0C */
uint32_t BSRR; /*gpio bit set/clear register address offset: 0x10 */
uint32_t BRR; /*gpio Port bit Clear Register address offset: 0x14 */
Puzhong stm32f1xx Development Strategy
www.prechin.cn
43
uint16_t Lckr; /*gpio Port configuration Lock Register Address offset: 0x18 */
}gpio_typedef;
This code declares a struct type named Gpio_typedef with the TYPEDEF keyword,
There are 7 member variables in the body, and the variable names correspond to the names of the registers exactly. The grammar of the C language stipulates that
The storage space of variables in the structure is continuous, where 32-bit variables occupy 4 bytes and 16-bit variable
The amount of 2 bytes consumed.
In other words, we define this gpio_typedef, if the first address of the struct is
0X4001 1000 (This is also the address of the first member variable CRL), then the second member of the struct
The variable CRH address is 0x4001 +0x04, plus this 0x04, which represents CRH
The offset of the 4-byte address occupied by the other member variables, relative to the first address of the struct,
The comment to the right of the above code is given.
This address offset corresponds to the register address offset one by one defined by the STM32 GPIO peripheral, as long as
By setting the first address of the structure, the address of the member in the structure can be determined, and then the structure can be
In the form of access registers, such as we still output the GPIOC0 low level, the specific code is as follows:
Gpio_typedef * GPIOX; Defines a gpio_typedef-type struct-body pointer gpiox
Gpiox = Gpioc_base; Set the pointer address to the macro gpioc_base address
GPIOX->BSRR = (1<< (16+0)); Accessing and modifying the GPIOC_BSRR register via pointers
This code first defines a struct pointer gpiox with the GPIO_TYPEDEF type, and lets the pointer refer to the
Address Gpioc_base to the GPIOC base site, and then access the structure based on the C language
Write the register with GPIOX->BSRR. For easier and more flexible operation, we use the macro definition directly.
Gpio_typedef type of pointer, and the pointer points to the first address of each Gpio port, and when used I
You can use this macro to access the register directly. The specific code is as follows:
#define GPIOA ((GPIO_TYPEDEF *) gpioa_base)
#define GPIOB ((GPIO_TYPEDEF *) gpiob_base)
#define GPIOC ((GPIO_TYPEDEF *) gpioc_base)
#define GPIOD ((GPIO_TYPEDEF *) gpiod_base)
#define GPIOE ((GPIO_TYPEDEF *) gpioe_base)
#define GPIOF ((GPIO_TYPEDEF *) gpiof_base)
#define GPIOG ((GPIO_TYPEDEF *) gpiog_base)
GPIOC->BSRR = (1<< (16+0));
Here we just take the gpio peripheral as an example, to explain how to use C-language to register
The same method is used for other peripherals. In fact, after the preparation of the experimental procedure,
We are all using the St company's firmware library, they have STM32 all the peripherals have been packaged,
We just need to call. We're here to analyze the encapsulation process just to make people understand more clearly
How to use C to encapsulate a register.
Embedded C language Development---memory and registers