库函数皱形

101046_Liw1_3768017.png

图为  储存器对应控制GPIO 以及时钟外设等地址

编写库函数时  使用到了C语言的强制转换,将指针指向向对应的GPIO外设和时钟等地址,避免了类似寄存器学要多个定义每个特有功能的寄存器。

比较如下:

库函数

#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;

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

#endif
 

寄存器

#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  。然后通过指针操作,相比之下工作轻松多了。

下面我们来讲他的原理 :

102532_x59u_3768017.png

寄存器之间偏移地址为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

会发现本质就是地址的访问

 

转载于:https://my.oschina.net/u/3768017/blog/1817594

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值