当前位置:网站首页>Building the prototype of library functions -- refer to the manual of wildfire
Building the prototype of library functions -- refer to the manual of wildfire
2022-07-06 02:20:00 【Fecter11】
I didn't follow the video in this part ( The technique in the video is smooth and fast , It's a little hard for my slow-paced ), So here I choose to study with the teaching manual of wildfire .
Build the prototype of library functions by yourself
Define the peripheral register structure
When we operate registers , The operation is the absolute address of all registers , If every peripheral register operates like this , That would be very troublesome . We consider that the address of the peripheral register is based on the bias of the peripheral base address
Move address , They are all incremented one by one on the base address of the peripheral , Each register takes up 32 Bytes , It's like the members of a structure . So we can Define a peripheral structure , The address of the structure is equal to the base address of the peripheral
( such as :
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef struct
{
uint32_t CRL;
uint32_t CRH;
uint32_t IDR;
uint32_t ODR;
uint32_t BSRR;
uint32_t BRR;
uint32_t LCKR;
}GPIO_TypeDef;
#define GPIOB ((GPIO_TypeDef*)GPIOB_BASE)
),
The members of this structure are all registers under the peripheral , Members are arranged in the same order as registers .
So we don't have to find the absolute address every time we operate the register , As long as you know the base address of the peripheral, you can operate all the registers of the peripheral , The members of the operation structure are directly configured registers .
Then the first is the definition of structure :
#define __IO volatile//volatile Represents variable
typedef struct // Define a structure ,GPIO The memory part of
{
uint32_t CRL;// Port configuration low register , Address offset 0X00
uint32_t CRH;// Port configuration high register , Address offset 0X04
uint32_t IDR;// Port data input register , Address offset 0X08
uint32_t ODR;// Port data output register , Address offset 0X0C
uint32_t BSRR;// Port bit settings / Clear register , Address offset 0X10
uint32_t BRR;// Port bit clear register , Address offset 0X14
uint32_t LCKR;// Port configuration lock register , Address offset 0X18
}GPIO_TypeDef; // This is the structure type name GPIO_TypeDef
typedef struct// Define a structure ,RCC The memory part of
{
uint32_t CR;// Clock control register offset 0x00
uint32_t CFGR;// Clock configuration register Address offset 0X04
uint32_t CIR;// Clock interrupt register , Address offset 0X08
uint32_t APB2RSTR;// APB2 Peripheral reset register , Address offset 0X0C
uint32_t APB1RSTR;// APB1 Peripheral reset register , Address offset 0X10
uint32_t AHBENR;// AHB Peripheral clock enable register , Address offset 0X14
uint32_t APB2ENR;// APB2 Peripheral clock enable register , Address offset 0X18
uint32_t APB1ENR;// APB1 Peripheral clock enable register , Address offset 0X1C
uint32_t BDCR ;// Backup domain control register , Address offset 0X20
uint32_t CSR;// control / Status register , Address offset 0X24
}RCC_TypeDef;// The type name of the structure RCC_TypeDef
#define GPIOB ((GPIO_TypeDef*)GPIOB_BASE)// First, use the structure pointer to point to our peripheral base address , Then rename it using the macro definition
This code adds a... Before each structure member “__IO” Prefix , Its prototype is in the first line of this code , On behalf of C Keywords in language “volatile”, stay C In language, this keyword is used to indicate that the variable is mutable , Ask the compiler not to optimize .
Members of these structures , All represent registers , Most of the time, registers are controlled by peripherals or STM32 Chip state modification , That is to say, even if CPU Modify these variables without executing code , The value of the variable may also be modified by peripherals 、 to update , So every time you use these variables , We all ask CPU Go to the address of the variable and visit again .
Without this keyword modification , In some cases , The compiler thinks there is no code to modify the variable , Directly from CPU Get the variable value from a cache of , At this time, the execution speed can be accelerated , But what is in this cache is stale data , It may be different from the latest state of the register we require .
Peripheral memory mapping
Look back at the structure of the encapsulated register , We should be able to realize . The premise of operating the register is to find the address of the peripheral . So we still need to use macro definitions to rename .

// First, the internal and external devices BLOCK2 From
# define PERIPH_BASE ((unsigned int)0x40000000) // If you write directly 0x4000 0000 The compiler will not treat this number as an address , So we use forced type conversion (unsigned int)
// We check the reference manual value to GPIO It's all hanging in APB2 On this bus
// We use it BLOCK2 The bus base address can be found by adding the offset to the starting address of
# define APB2PERIPH_BASE (PERIPH_BASE + 0x10000 )// By adding an offset , You can get the bus APB2 The base address
// operation GPIO You also need to configure RCC Clock register , and RCC It's hanging on AHB On the bus , Here we will DMA1 The address of AHB Bus base address of , The offset is 0x00020000
# define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
// Next, you need to configure the peripheral address
//GPIO These ports are in APB2 On this bus
// Just add their offset directly
#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)
//RCC Peripheral base address
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
Peripheral statement
Define the peripheral register structure , After realizing peripheral memory mapping , We then cast the base address of the peripheral into the register structure pointer of the corresponding peripheral , Then declare the pointer as a peripheral name , thus , The name of the peripheral corresponds to the address of the peripheral , Moreover, the peripheral name is also a pointer to the register structure of the peripheral type , All registers of the peripheral can be directly operated through the pointer .
The above paragraph is simply , The register structure will be created , It is associated with the peripheral base address in the form of structure pointer , Then rename it using the macro definition .
// GPIO Peripheral statement
#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)
// RCC Peripheral statement
#define RCC ((RCC_TypeDef *) RCC_BASE)
/*RCC Of AHB1 Clock enable register address , Cast to pointer */
//efine RCC_APB2ENR *(unsigned int*)(RCC_BASE + 0x18)//0x18 Is the offset of the clock enable register
We go back to main.c In the document
/* * C language knowledge , Conditional compilation * #if It's true * Execute the procedure here * #else * Otherwise, execute the procedure here * #endif */
// Use the register structure pointer to illuminate LED
int main(void)
{
#if 0 // Control registers directly by manipulating memory
// Turn on GPIOB Port clock
RCC_APB2ENR |= (1<<3);
// Clear the control PB0 Port bit
GPIOB_CRL &= ~( 0x0F<< (4*0));
// To configure PB0 For universal push-pull output , Speed is 10M
GPIOB_CRL |= (1<<4*0);
// PB0 Output Low level
GPIOB_ODR |= (0<<0);
while (1);
#else // The register structure pointer is used to control the register
// Turn on GPIOB Port clock
RCC->APB2ENR |= (1<<3); //IO port B The clock is on
// Clear the control PB0 Port bit
GPIOB->CRL &= ~( 0x0F<< (4*0));
// To configure PB0 For universal push-pull output , Speed is 10M
GPIOB->CRL |= (1<<4*0);
// PB0 Output Low level
GPIOB->ODR |= (0<<0);
while (1);
#endif
}
Define bit operation functions
stay “stm32f10x_gpio.c” The file defines two bit operation functions , It is used to control the pin output high level and low level respectively .
Review the code above to define GPIO Corresponding structure , In addition, the memory mapping is realized by macro definition ( It is associated with the peripheral address through the macro definition ).
Our next goal is to encapsulate these two parts in a function .
First look at the code
// The first is the set function
/* The functionality : Set pin to high level Parameter description :GPIOx: The parameter is GPIO_TypeDef Pointer to type , Point to GPIO The address of the port GPIO_Pin: Select the desired GPIO Port pins , The macro definitions we use GPIO_Pin_0-15 Express GPIOx Port of 0-15 Pin No . */
void GPIO_SetBits(GPIO_TypeDef * GPIOx,uint16_t GPIO_pin) //GPIO Set function . Formal parameters include ports ( peripherals ), as well as 16 individual io(BSRR Register bit of , This disposal 1 pull up . The operation is BSy)
{
// Setting we use port bit setting / Clear register BSRR.
/* Set up GPIOx Of BSRR The first of the registers GPIO_pin position , Make it output high level . macro GPIO_Pin Just corresponding bit 1, The others are 0, You can assign values directly , You can also use or equal to */
GPIOx->BSRR |= GPIO_pin; //GPIOx Of BSRR, The reset value is 0x00000000
//GPIOx->BSRR = GPIO_pin;
}
// Then there is the reset function
/* The functionality : Set the pin to low level Parameter description :GPIOx: The parameter is GPIO_TypeDef Pointer to type , Point to GPIO The address of the port GPIO_Pin: Select the GPIO Port pins , You can enter macros GPIO_Pin_0-15, Express GPIOx Port of 0-15 Pin No . */
void GPIO_ResetBits(GPIO_TypeDef * GPIOx,uint16_t GPIO_pin) //GPIO Reset function . Formal parameters include ports ( peripherals ), as well as 16 individual io(BRR Register bit of , Set up 1 Zero clearing )
{
GPIOx->BRR |= GPIO_pin; // The operation here BRR register ,BRR The characteristic of register is to set 1 Will clear the corresponding ODR Position as 0. The reset value is 0x00000000
/* Set up GPIOx port BRR The first of the registers GPIO_Pin position , Make it output low level . macro GPIO_Pin Only the corresponding bit is 1, Other bits are 0, So you can assign values directly . /* } We will now look at the above two functions , Its main purpose is to GPIOx The register of BSRR perhaps BRR Register assignment , Thus, the operation pin outputs high level or low level . operation BSRR Or the BRR You can operate a bit alone .
GPIOx Is a pointer variable , Through the input parameters of the function, we can modify its value , Such as assignment GPIOA,GPIOB,GPIOC And so on , This function can control the output of these ports .
边栏推荐
- 500 lines of code to understand the principle of mecached cache client driver
- Redis string type
- 【无标题】数据库中一条查询SQL执行的过程
- vs code保存时 出现两次格式化
- LeetCode 103. Binary tree zigzag level order transverse - Binary Tree Series Question 5
- The intelligent material transmission system of the 6th National Games of the Blue Bridge Cup
- 同一个 SqlSession 中执行两条一模一样的SQL语句查询得到的 total 数量不一样
- Know MySQL database
- Extracting key information from TrueType font files
- SPI communication protocol
猜你喜欢

Prepare for the autumn face-to-face test questions

Leetcode3. Implement strstr()

Black high-end responsive website dream weaving template (adaptive mobile terminal)
![抓包整理外篇——————状态栏[ 四]](/img/1e/2d44f36339ac796618cd571aca5556.png)
抓包整理外篇——————状态栏[ 四]

Overview of spark RDD

Blue Bridge Cup embedded_ STM32_ New project file_ Explain in detail
![[solution] every time idea starts, it will build project](/img/fc/e68f3e459768abb559f787314c2124.jpg)
[solution] every time idea starts, it will build project

LeetCode 103. Binary tree zigzag level order transverse - Binary Tree Series Question 5
![[width first search] Ji Suan Ke: Suan tou Jun goes home (BFS with conditions)](/img/ec/7fcdcbd9c92924e765d420f7c71836.jpg)
[width first search] Ji Suan Ke: Suan tou Jun goes home (BFS with conditions)

Blue Bridge Cup embedded_ STM32 learning_ Key_ Explain in detail
随机推荐
Thinking about the best practice of dynamics 365 development collaboration
It's wrong to install PHP zbarcode extension. I don't know if any God can help me solve it. 7.3 for PHP environment
在线怎么生成富文本
This time, thoroughly understand the deep copy
The third level of C language punch in
Initial understanding of pointer variables
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
Global and Chinese markets of nasal oxygen tubes 2022-2028: Research Report on technology, participants, trends, market size and share
Global and Chinese market of commercial cheese crushers 2022-2028: Research Report on technology, participants, trends, market size and share
使用npm发布自己开发的工具包笔记
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
MySQL learning notes - subquery exercise
Unity learning notes -- 2D one-way platform production method
2022 edition illustrated network pdf
500 lines of code to understand the principle of mecached cache client driver
数据工程系列精讲(第四讲): Data-centric AI 之样本工程
Have a look at this generation
Get the relevant information of ID card through PHP, get the zodiac, get the constellation, get the age, and get the gender
抓包整理外篇——————状态栏[ 四]
[depth first search] Ji Suan Ke: Betsy's trip