wordpress站内优化,国内景观设计公司前十名,ngx wordpress 403,宁波外贸网站设计公司在51单片机中#xff1a; 首先我们看看 51 中是怎么做的。51 单片机开发中经常会引用一个 reg51.h 的头文件#xff0c;下面我们看看他是怎么把名字和寄存器联系起来的#xff1a;
sfr P0 0x80;sfr 也是一种扩充数据类型#xff0c;点用一个内存单元#xff0c;值域为 0 首先我们看看 51 中是怎么做的。51 单片机开发中经常会引用一个 reg51.h 的头文件下面我们看看他是怎么把名字和寄存器联系起来的
sfr P0 0x80;sfr 也是一种扩充数据类型点用一个内存单元值域为 0255。利用它可以访问 51 单片 机内部的所有特殊功能寄存器。如用 sfr P1 0x90 这一句定义 P1 为 P1 端口在片内的寄存 器。然后我们往地址为 0x80 的寄存器设值的方法是P0value; 在STM32中 在 STM32 中同样也可以这样做但是 STM32 因为寄存器太多太多如果以这样的方式一一列出来那要好大的篇幅既不方便开发也显得太杂乱无序的感觉。所以 MDK 采用的方式是通过结构体来将寄存器组织在一起。下面我们就讲解 MDK 是怎么把结构体和地址对应起来的为什么我们修改结构体成员变量的值就可以达到操作对应寄存器的值。这些事情都是在stm32f10x.h文件中完成的。我们通过 GPIOA 的几个寄存器的地址来讲解。 1寄存器地址映射表 从这个表我们可以看出GPIOA 的 7 个寄存器都是 32 位的所以每个寄存器占有 4个地址一共占用 28 个地址地址偏移范围为000h~01Bh。这个地址偏移是相对 GPIOA的基地址而言的。GPIOA 的基地址是怎么算出来的呢因为 GPIO 都是挂载在 APB2 总线之上所以它的基地址是由 APB2 总线的基地址GPIOA 在 APB2 总线上的偏移地址决定的。同理依次类推我们便可以算出 GPIOA 基地址了。下面我们打开 stm32f10x.h 定位到 GPIO_TypeDef 定义处
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;然后定义到
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)GPIOA 是将 GPIOA_BASE 强制转换为 GPIO_TypeDef 指针这句话的意思是GPIOA 指向地址GPIOA_BASEGPIOA_BASE 存放的数据类型为 GPIO_TypeDef。
然后查看 GPIOA_BASE的宏定义
#define GPIOA_BASE (APB2PERIPH_BASE 0x0800)可知GPIOA 的基地址是 APB2 总线的基地址GPIOA 在 APB2 总线上的偏移地址
依次类推可以找到最顶层
#define APB2PERIPH_BASE (PERIPH_BASE 0x10000)
#define PERIPH_BASE ((uint32_t)0x40000000)所以我们便可以算出 GPIOA 的基地址位
GPIOA_BASE 0x400000000x100000x08000x400108002GPIOA 的 7 个寄存器的地址如何计算
GPIOA 的寄存器的地址GPIOA 基地址寄存器相对 GPIOA 基地址的偏移值这个偏移值在上面的寄存器地址映像表中可以查到。
3结构体里面这些寄存器又是怎么与地址一一对应的 这里就涉及到结构体的一个特征那就是结构体存储的成员他们的地址是连续的。上面讲到 GPIOA 是指向GPIO_TypeDef 类型的指针又由于 GPIO_TypeDef 是结构体所以自然而然我们就可以算出 GPIOA 指向的结构体成员变量对应地址了。 我们可以把 GPIO_TypeDef 的定义中的成员变量的顺序和 GPIOx 寄存器地址映像对比可以发现他们的顺序是一致的如果不一致就会导致地址混乱了。这就是为什么固件库里面GPIOA-BRRvalue;就是设置地址为 0x400108000x014(BRR 偏移量)0x40010814 的寄存器 BRR 的值了。它和 51 里面 P0value 是设置地址为 0x80 的 P0 寄存器的值是一样的道理。