庫函數皺形

圖爲  儲存器對應控制GPIO 以及時鐘外設等地址函數

編寫庫函數時  使用到了C語言的強制轉換,將指針指向向對應的GPIO外設和時鐘等地址,避免了相似寄存器學要多個定義每一個特有功能的寄存器。ui

比較以下:指針

庫函數原理

#ifndef stm32__H__
#define stm32__H__
#define PERIPH_BASE ((unsigned int)0x40000000)  //stmf103外設總基地址
#define AHBPERIPH_BASE  (PERIPH_BASE+0x20000)
#define APB1PERIPH_BASE (PERIPH_BASE)
#define APB2PERIPH_BASE (PERIPH_BASE+0x10000)
#define RCC_BASE        (AHBPERIPH_BASE+0x1000)
#define GPIOB_BASE      (APB2PERIPH_BASE+0x0c00)
#define uint_32t  unsigned int 
#define uint_16t  unsigned short
#define uint_8t   unsigned char
typedef struct{
    uint_32t CRL;
    uint_32t CRH;
    uint_32t IDR;
    uint_32t ODR;
    uint_32t BSRR;
    uint_32t BRR;
    uint_32t LCKR;
}GPIO_Typedef;
typedef struct{
 uint_32t RCC_CR;
 uint_32t    RCC_CFGR;
 uint_32t RCC_CIR;
 uint_32t RCC_APB2RSTR;
 uint_32t RCC_APB1RSTR;
 uint_32t RCC_AHBENR;
 uint_32t RCC_APB2ENR;
 uint_32t RCC_APB1ENR;
 uint_32t RCC_BDCR;
 uint_32t RCC_CSR;
 uint_32t RCC_AHBRSTR;
}RCC_Typedef;im

#define  GPIOB ((GPIO_Typedef*)(GPIOB_BASE))
#define  RCC   ((RCC_Typedef*)(RCC_BASE))img

#endif
 語言

寄存器di

#ifndef  STM32_H
#define  STM32_H
#define  PERIPH_BASE   ((unsigned int)0x40000000)
#define  APB1PERIPH    PERIPH_BASE
#define  AHBPERIPH_BASE (PERIPH_BASE+0x20000)
#define  APB2PERIPH_BASE   (PERIPH_BASE+0x10000)
#define  RCC_BASE      (AHBPERIPH_BASE+0x1000)
//基地址
#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+0x2c00)
#define  GPIOG_BASE  (APB2PERIPH_BASE+0x3000)工作

#define  RCC_APB2ENR *(unsigned int*)(RCC_BASE+0x18)結構體

//低位寄存器
#define  GPIOA_CRL   *(unsigned int*)(GPIOA_BASE+0x00)
#define  GPIOB_CRL   *(unsigned int*)(GPIOB_BASE+0x00)
#define  GPIOC_CRL   *(unsigned int*)(GPIOC_BASE+0x00)
#define  GPIOD_CRL   *(unsigned int*)(GPIOD_BASE+0x00) 
#define  GPIOE_CRL   *(unsigned int*)(GPIOE_BASE+0x00)
#define  GPIOF_CRL   *(unsigned int*)(GPIOF_BASE+0x00)
#define  GPIOG_CRL   *(unsigned int*)(GPIOG_BASE+0x00)
//高位寄存器
#define  GPIOA_CRH   *(unsigned int*)(GPIOA_BASE+0x04)
#define  GPIOB_CRH   *(unsigned int*)(GPIOB_BASE+0x04)
#define  GPIOC_CRH   *(unsigned int*)(GPIOC_BASE+0x04)
#define  GPIOD_CRH   *(unsigned int*)(GPIOD_BASE+0x04)
#define  GPIOE_CRH   *(unsigned int*)(GPIOE_BASE+0x04)
#define  GPIOF_CRH   *(unsigned int*)(GPIOF_BASE+0x04)
#define  GPIOG_CRH   *(unsigned int*)(GPIOG_BASE+0x04)
    //輸出寄存器
#define  GPIOA_ODR   *(unsigned int*)(GPIOA_BASE+0x0c)
#define  GPIOB_ODR   *(unsigned int*)(GPIOB_BASE+0x0c)
#define  GPIOC_ODR   *(unsigned int*)(GPIOC_BASE+0x0c)
#define  GPIOD_ODR   *(unsigned int*)(GPIOD_BASE+0x0c)
#define  GPIOE_ODR   *(unsigned int*)(GPIOE_BASE+0x0c)
#define  GPIOF_ODR   *(unsigned int*)(GPIOF_BASE+0x0c)
#define  GPIOG_ODR   *(unsigned int*)(GPIOG_BASE+0x0c)

 //輸入寄存器
#define  GPIOA_IDR   *(unsigned int*)(GPIOA_BASE+0x08)
#define  GPIOB_IDR   *(unsigned int*)(GPIOB_BASE+0x08)
#define  GPIOC_IDR   *(unsigned int*)(GPIOC_BASE+0x08)
#define  GPIOD_IDR   *(unsigned int*)(GPIOD_BASE+0x08)
#define  GPIOE_IDR   *(unsigned int*)(GPIOE_BASE+0x08)
#define  GPIOF_IDR   *(unsigned int*)(GPIOF_BASE+0x08)
#define  GPIOG_IDR   *(unsigned int*)(GPIOG_BASE+0x08)

 //置位寄存器
#define  GPIOA_BSRR  *(unsigned int*)(GPIOA_BASE+0x10)
#define  GPIOB_BSRR  *(unsigned int*)(GPIOB_BASE+0x10)
#define  GPIOC_BSRR  *(unsigned int*)(GPIOC_BASE+0x10)
#define  GPIOD_BSRR  *(unsigned int*)(GPIOD_BASE+0x10)
#define  GPIOE_BSRR  *(unsigned int*)(GPIOE_BASE+0x10)
#define  GPIOF_BSRR  *(unsigned int*)(GPIOF_BASE+0x10)
#define  GPIOG_BSRR  *(unsigned int*)(GPIOG_BASE+0x10)
 //復位寄存器
#define  GPIOA_BRR   *(unsigned int*)(GPIOA_BASE+0x14)
#define  GPIOB_BRR   *(unsigned int*)(GPIOB_BASE+0x14)
#define  GPIOC_BRR   *(unsigned int*)(GPIOC_BASE+0x14)
#define  GPIOD_BRR   *(unsigned int*)(GPIOD_BASE+0x14)
#define  GPIOE_BRR   *(unsigned int*)(GPIOE_BASE+0x14)
#define  GPIOF_BRR   *(unsigned int*)(GPIOF_BASE+0x14)
#define  GPIOG_BRR   *(unsigned int*)(GPIOG_BASE+0x14)
#endif

 

進過比較會發現   每一個GPIO 都須要定義   指定的寄存器並且每一個都不同,可是當咱們用庫函數時會發現咱們的工做量少了,只須要把GPIO的基地址映射出來,而後在定義結構體 GPIO_Typdef  ,在強制轉換爲GPIO_Typdef  。而後經過指針操做,相比之下工做輕鬆多了。

下面咱們來說他的原理 :

寄存器之間偏移地址爲0x04  (注意是十六進制,在編寫過程當中若是用十進制的話會訪問不到指定地址)

當我 們進行強轉時:  

#define  GPIOB ((GPIO_Typedef*)(GPIOB_BASE))   至關於把 GPIOB_BASE 的地址 做爲 指針GPIOB的首地址

GPIOB_BASE 的地址是 :0x40010c00 

寄存器

GPIOB_CRL    地址   GPIOB_BASE +偏移地址(0x00) 0x40010c00 

GPIOB_CRH  地址   GPIOB_BASE +偏移地址(0x04) 0x40010c04

庫函數

結構體 GPIO_Typdef 結構 的成員均爲int_32T  ,偏移地址爲4

當咱們 訪問  GPIOB ->CRL    (首個成員就是結構體指針的地址) 那麼 地址爲:0x40010c00 

                  訪問GPIOB->CRH  就是首個成員地址加上偏移地址   那麼  地址爲:0x40010c04

會發現本質就是地址的訪問

相關文章
相關標籤/搜索