STM32------C語言對寄存器的封裝


為了學習STM32時比較踏實,有必要了解固件庫底層是怎么操作的

GPIOA~F首地址

GPIOA 0x4002 0000
GPIOB 0x4002 0400
GPIOC 0x4002 0800
GPIOD 0x4002 0C00
GPIOE 0x4002 1000
GPIOF 0x4002 1400

 

 

 

 

 

 

以GPIOF口的GPIO_OSPEEDR寄存器為例

 1 typedef unsigned int uint32;
 2 //GPIOF內存塊的首地址
 3 #define   GPIOF_BASE     (0x4002 1400)
 4 //GPIO口寄存器
 5 #define   GPIO_MODER     *(uint32 *)(GPIO_BASE+0x00)
 6 #defien   GPIO_OTYPER    *(uint32 *)(GPIO_BASE+0x04)
 7 #define   GPIO_OSPEEDR   *(uint32 *)(GPIO_BASE+0x08)
 8 #define   GPIO_PUPDR     *(uint32 *)(GPIO_BASE+0x0C)
 9 #define   GPIO_IDR       *(uint32 *)(GPIO_BASE+0x10)
10 #define   GPIO_ODR       *(uint32 *)(GPIO_BASE+0x14)
11 #define   GPIO_LCKR      *(uint32 *)(GPIO_BASE+0x1C)
12 #define   GPIO_AFRL      *(uint32 *)(GPIO_BASE+0x20)
13 #define   GPIO_AFRH      *(uint32 *)(GPIO_BASE+0x24)

 這樣的話,我們如果要令GPIO_MODE寄存器的值全為F,GPIO_MODE=0xFFFF FFFF.

像上面這樣定義寄存器有一個缺點,就是這只是定義了一個GPIO口,如果要把所有GPIO口都定義了,那將會有很多這樣的定義,這樣太麻煩,而且也不太好閱讀。為了方便定義寄存器,我將用結構體,從上面寄存器的偏移地址可以看出,每個寄存器都是一個接着一個有序的排列,這就類似於C語言中的結構體。所以我們可以利用結構體來簡化定義。

 1 typedef unsigned int uint32;
 2 typedef unsigned short int uint16;
 3 #define GPIOA_BASE   (0x4002 0000)
 4 #define GPIOB_BASE   (0x4002 0400)
 5 #define GPIOC_BASE   (0x4002 0800)
 6 typedef struct
 7 {
 8     uint32 GPIO_MODER;
 9     uint32 GPIO_OTYPER; 
10     uint32 GPIO_OSPEEDR;   
11     uint32 GPIO_PUPDR; 
12     uint32 GPIO_IDR;   
13     uint32 GPIO_ODR;   
14     uint32 GPIO_LCKR;  
15     uint16 GPIO_AFRL;   
16     uint16 GPIO_AFRH;   
17 }GPIO_TypeDef;
18 
19 #define GPIOA  (GPIO_TypeDef *)GPIOA_BASE;
20 #define GPIOB  (GPIO_TypeDef *)GPIOB_BASE;
21 #define GPIOC  (GPIO_TypeDef *)GPIOC_BASE;
22 
23 GPIOA->GPIO_MODER=0xffffff;

 首先,我們定義每個GPIO的內存塊的首地址,然后定義一個結構體,里面的成員要按順序寫好寄存器的別名,接着我們用第19的宏定義,將GPIO的內存塊首地址強制轉換成指向結構體的指針,也就是結構體的首地址就是GPIO內存塊的首地址,最后我們可以利用成員符號,對每個寄存器進行寫入數據或者讀取數據。

STM32中固件庫到底是什么 

STM32內部里有一個叫總線的東西有APB1,APB2,APB3,AHB1,AHB2總線,總線也是有地址的,固件庫是怎么利用總線的地址來尋到每個寄存器呢?

 1 #define PERIPH_BASE           ((uint32_t)0x40000000)
 2 #define APB1PERIPH_BASE       PERIPH_BASE
 3 #define APB2PERIPH_BASE       (PERIPH_BASE + 0x00010000)
 4 #define AHB1PERIPH_BASE       (PERIPH_BASE + 0x00020000)
 5 #define AHB2PERIPH_BASE       (PERIPH_BASE + 0x10000000)
 6 
 7 #define GPIOA_BASE            (AHB1PERIPH_BASE + 0x0000)
 8 #define GPIOB_BASE            (AHB1PERIPH_BASE + 0x0400)
 9 #define GPIOC_BASE            (AHB1PERIPH_BASE + 0x0800)
10 #define GPIOD_BASE            (AHB1PERIPH_BASE + 0x0C00)
11 #define GPIOE_BASE            (AHB1PERIPH_BASE + 0x1000)
12 #define GPIOF_BASE            (AHB1PERIPH_BASE + 0x1400)
13 #define GPIOG_BASE            (AHB1PERIPH_BASE + 0x1800)
14 #define GPIOH_BASE            (AHB1PERIPH_BASE + 0x1C00)
15 #define GPIOI_BASE            (AHB1PERIPH_BASE + 0x2000)
16 #define GPIOJ_BASE            (AHB1PERIPH_BASE + 0x2400)
17 #define GPIOK_BASE            (AHB1PERIPH_BASE + 0x2800)

 原理跟上面不一樣只不過,固件庫利用總線的首地址來尋找每個外設的地址。 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM