单片机的那些事

库文件和参考手册

本文以自己的理解进行总结,如有问题,可提出

寄存器和库函数的联系

学过单片机的都清楚,一款MCU芯片包含内核,外设,存储器等,内部和这些外设都是由系统总线控制。以Cortex-M3为例,32位访问地址,拥有4G的访问空间,0x00000000~0xFFFFFFFF。如图所示,为存储器映射,ARM架构规定了每一块空间是什么。
存储器映射
而库函数对GPIO,USART的操作,最终以系统总线,读写这些地址。如下图所示,为stm32f103的寄存器GPIO的地址。
在这里插入图片描述
以HAL库GPIOA为例,可以找到以下三行的定义(stm32f1xx.h):

#define PERIPH_BASE           0x40000000UL 
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x00010000UL)
#define GPIOA_BASE            (APB2PERIPH_BASE + 0x00000800UL)

不难看出,GPIOA_BASE == 0x40010800,对应了上图的GPIO Port A。然后HAL又定义的以下宏定义,可以看到是一个指针,在C语言指针,表示指向某一个地址,也就是说GPIOA指向了0x40010800这个地址。

#define GPIOA               ((GPIO_TypeDef *)GPIOA_BASE)

到这里可能就想到,为什么是GPIO_TypeDef类型,我们接着往下看,如下图参考手册的GPIO寄存器和代码:

typedef struct
{
  __IO uint32_t CRL;
  __IO uint32_t CRH;
  __IO uint32_t IDR;
  __IO uint32_t ODR;
  __IO uint32_t BSRR;
  __IO uint32_t BRR;
  __IO uint32_t LCKR;
} GPIO_TypeDef;

在这里插入图片描述
从这里是不是可以看出, GPIO_TypeDef这个结构体定义了,GPIO的寄存器。为什么顺序上会一致,如下图,可以看到CRL和CRH里 ADDrees offset, 在看看GPIO_TypeDef 定义的类型 uint32_t。

在这里插入图片描述
在这里插入图片描述
没错,uint32_t是4个字节,而这个寄存器占用了4个字节,在结构体中,字节会依次从上往下会依次叠加,(当然·这里也有其他东西,结构体里数据类型的存放位置会影响到内存的使用率,后面将介绍),所以GPIO->CRL的地址为 0x40010800,GPIO->CRL的地址为 0x40010804,这样就可以对GPIOA的寄存器配置,实现各个外设的功能,当然·一些外设会需要其他外设配置才能实现功能,比如这里还需要RCC这个寄存器。
我们也可以看看nxp的库,如下代码和图片(MIMXRT1062.h),RT1602这款芯片:

#define GPIO1_BASE                               (0x401B8000u)
#define GPIO1                                    ((GPIO_Type *)GPIO1_BASE)

typedef struct {
  __IO uint32_t DR;                                /**< GPIO data register, offset: 0x0 */
  __IO uint32_t GDIR;                              /**< GPIO direction register, offset: 0x4 */
  __I  uint32_t PSR;                               /**< GPIO pad status register, offset: 0x8 */
  __IO uint32_t ICR1;                              /**< GPIO interrupt configuration register1, offset: 0xC */
  __IO uint32_t ICR2;                              /**< GPIO interrupt configuration register2, offset: 0x10 */
  __IO uint32_t IMR;                               /**< GPIO interrupt mask register, offset: 0x14 */
  __IO uint32_t ISR;                               /**< GPIO interrupt status register, offset: 0x18 */
  __IO uint32_t EDGE_SEL;                          /**< GPIO edge select register, offset: 0x1C */
       uint8_t RESERVED_0[100];
  __O  uint32_t DR_SET;                            /**< GPIO data register SET, offset: 0x84 */
  __O  uint32_t DR_CLEAR;                          /**< GPIO data register CLEAR, offset: 0x88 */
  __O  uint32_t DR_TOGGLE;                         /**< GPIO data register TOGGLE, offset: 0x8C */
} GPIO_Type;

在这里插入图片描述在这里插入图片描述

总结

本文只是讲解库函数和参考手册的关系,后续会讲到如何实现一个外设的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值