2019-03-23 20:05发布
以固件库v3.5为例第一步:#define FLASH_BASE ((uint32_t)0x08000000) #define SRAM_BASE ((uint32_t)0x20000000) #define PERIPH_BASE ((uint32_t)0x40000000)#define SRAM_BB_BASE ((uint32_t)0x22000000)#define PERIPH_BB_BASE ((uint32_t)0x42000000) #define FSMC_R_BASE ((uint32_t)0xA0000000)以PERIPH_BASE为例:说明,mcu把所有外设的寄存器地址在40000000开始向后0x22000000之前的单元中。这是也可以看出mcu设计者的设计思想。
第二步:在第一步的基础上进一步分段#define APB1PERIPH_BASE PERIPH_BASE#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)我们可以看出,以PERIPH_BASE(40000000)为首地址的寄存器段分三部分 :挂在总线APB1的外设,挂在总线APB2的外设,挂在高速总线AHB的外设分别对应:APB1PERIPH_BASE,APB2PERIPH_BASE,AHBPERIPH_BASE
第三步:在第二步的基础上进一步分段#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 + 0x1C00)其它外设的基地址定义也如此,至此可以大致看到,各外设寄存器的大致分布。
第四步:在前三步的基础上进行具体定义#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)可以看出GPIOA是指向GPIOA_BASE基地址的,结构体指针。第一,这个机构体各个成员就是这个外设的配置寄存器第二,这个结构体的各成员顺序,不能变。因为各外设的配置寄存器地址是死的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;这样各功能外设的寄存器地址,就映射到 其对应的结构体指针上了。如访问 GPIOA->CRL
最多设置5个标签!
以固件库v3.5为例
第一步:
#define FLASH_BASE ((uint32_t)0x08000000)
#define SRAM_BASE ((uint32_t)0x20000000)
#define PERIPH_BASE ((uint32_t)0x40000000)
#define SRAM_BB_BASE ((uint32_t)0x22000000)
#define PERIPH_BB_BASE ((uint32_t)0x42000000)
#define FSMC_R_BASE ((uint32_t)0xA0000000)
以PERIPH_BASE为例:
说明,mcu把所有外设的寄存器地址在40000000开始向后0x22000000之前的单元中。
这是也可以看出mcu设计者的设计思想。
第二步:在第一步的基础上进一步分段
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
我们可以看出,以PERIPH_BASE(40000000)为首地址的寄存器段
分三部分 :挂在总线APB1的外设,挂在总线APB2的外设,挂在高速总线AHB的外设
分别对应:APB1PERIPH_BASE,APB2PERIPH_BASE,AHBPERIPH_BASE
第三步:在第二步的基础上进一步分段
#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 + 0x1C00)
其它外设的基地址定义也如此,
至此可以大致看到,各外设寄存器的大致分布。
第四步:在前三步的基础上进行具体定义
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)
可以看出GPIOA是指向GPIOA_BASE基地址的,结构体指针。
第一,这个机构体各个成员就是这个外设的配置寄存器
第二,这个结构体的各成员顺序,不能变。因为各外设的配置寄存器地址是死的
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;
这样各功能外设的寄存器地址,就映射到 其对应的结构体指针上了。
如访问 GPIOA->CRL
一周热门 更多>