当前位置:网站首页>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 .
边栏推荐
- Selenium element positioning (2)
- General process of machine learning training and parameter optimization (discussion)
- Using SA token to solve websocket handshake authentication
- Global and Chinese market of commercial cheese crushers 2022-2028: Research Report on technology, participants, trends, market size and share
- Keyword static
- Overview of spark RDD
- Computer graduation design PHP part-time recruitment management system for College Students
- Executing two identical SQL statements in the same sqlsession will result in different total numbers
- 【MySQL 15】Could not increase number of max_open_files to more than 10000 (request: 65535)
- 同一个 SqlSession 中执行两条一模一样的SQL语句查询得到的 total 数量不一样
猜你喜欢
零基础自学STM32-复习篇2——使用结构体封装GPIO寄存器
Lecture 4 of Data Engineering Series: sample engineering of data centric AI
同一个 SqlSession 中执行两条一模一样的SQL语句查询得到的 total 数量不一样
PHP campus movie website system for computer graduation design
Leetcode sum of two numbers
Minecraft 1.16.5 生化8 模组 2.0版本 故事书+更多枪械
【MySQL 15】Could not increase number of max_open_files to more than 10000 (request: 65535)
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
Computer graduation design PHP enterprise staff training management system
从顶会论文看2022年推荐系统序列建模的趋势
随机推荐
【机器人库】 awesome-robotics-libraries
Install redis
[robot library] awesome robots Libraries
RDD conversion operator of spark
Bigder:34/100 面试感觉挺好的,没有收到录取
General process of machine learning training and parameter optimization (discussion)
Global and Chinese markets for single beam side scan sonar 2022-2028: Research Report on technology, participants, trends, market size and share
一题多解,ASP.NET Core应用启动初始化的N种方案[上篇]
[coppeliasim] efficient conveyor belt
This time, thoroughly understand the deep copy
剑指 Offer 29. 顺时针打印矩阵
Know MySQL database
SSM 程序集
Overview of spark RDD
论文笔记: 极限多标签学习 GalaXC (暂存, 还没学完)
0211 embedded C language learning
How to improve the level of pinduoduo store? Dianyingtong came to tell you
Black high-end responsive website dream weaving template (adaptive mobile terminal)
Global and Chinese markets of nasal oxygen tubes 2022-2028: Research Report on technology, participants, trends, market size and share
vs code保存时 出现两次格式化