寄存器映射
程序员文章站
2022-07-03 16:33:28
...
寄存器映射原理
首先看下这行代码
((unsigned int *)(GPIOB_BASE+0X00))
其中GPIOB_BASE
是GPIOB寄存器的起始地址,它是一个4字节(32位)的地址。但是电脑不知道它地址,因此需要在前面加一个(unsigned int *)
对其进行强制类型转换,这个的作用就是把GPIOB_BASE + 0x00
强制转化为地址,因为*
符号运算的是地址,所以(unsigned int *)(GPIOB_BASE + 0x00)
这一串就成了地址,相当与一个指针常量,当需要向其写入或者读取数据时就可以按按照指针的操作方式对其进行操作,如
*((unsigned int *)(GPIOB_BASE+0X00)) = 0xffffffff; // 向GPIOB_BASE内写入 0xFFFFFFFF;
然后看下这行代码
#define GPIOB ((GPIO_TypeDef *)GPIOB_BASE)
这个是把GPIOB_BASE
这个地址强制转换为GPIO_TypeDef
结构体类型的基地址,GPIOB_BASE
它的地址分配就和结构体一样了,((GPIO_TypeDef *)GPIOB_BASE)
相当于一个结构体指针,因此就可以对结构体成员进行操作了。
这里是STM32
的库函数中的RCC
寄存器地址映射代码
//定义RCC寄存器的基地址
#define RCC_BASE (AHB1PERIPH_BASE + 0x3800)
//使用结构体来自动对齐RCC相关寄存器
//因为寄存器是32位/4字节,并且是连续的
//根据结构体数据的特性,使用 unsigned int (32位/4字节)可实现自动对齐
//__IO #define __IO volatile
//uint32_t typedef unsigned int uint32_t;
//RESERVED1[] : 保留地址,因为有些寄存器地址不连续,所以要对其进行占位,达到对齐的目的
typedef struct
{
__IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */
__IO uint32_t PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */
__IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */
__IO uint32_t CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */
__IO uint32_t AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */
__IO uint32_t AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */
__IO uint32_t AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */
uint32_t RESERVED0; /*!< Reserved, 0x1C */
__IO uint32_t APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */
__IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */
uint32_t RESERVED1[2]; /*!< Reserved, 0x28-0x2C */
__IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */
__IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */
__IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */
uint32_t RESERVED2; /*!< Reserved, 0x3C */
__IO uint32_t APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */
__IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */
uint32_t RESERVED3[2]; /*!< Reserved, 0x48-0x4C */
__IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */
__IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */
__IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */
uint32_t RESERVED4; /*!< Reserved, 0x5C */
__IO uint32_t APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */
__IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */
uint32_t RESERVED5[2]; /*!< Reserved, 0x68-0x6C */
__IO uint32_t BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */
__IO uint32_t CSR; /*!< RCC clock control & status register, Address offset: 0x74 */
uint32_t RESERVED6[2]; /*!< Reserved, 0x78-0x7C */
__IO uint32_t SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */
__IO uint32_t PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */
__IO uint32_t PLLSAICFGR; /*!< RCC PLLSAI configuration register, Address offset: 0x88 */
__IO uint32_t DCKCFGR; /*!< RCC Dedicated Clocks configuration register, Address offset: 0x8C */
} RCC_TypeDef;
// 将RCC_BASE 转换为RCC_TypeDef型指针
// 这样结构体就和寄存器地址一一对应起来了 寄存器映射
// 使用指针RCC 即可对其进行访问。
#define RCC ((RCC_TypeDef *) RCC_BASE)
这是RCC寄存器映射表,(详细的映射表请看STM32F4XX参考手册)