要操作寄存器,实际是操作对应地址的数据。如GPIOA->ODR = 0,将GPIOA的所有端口输出置位0.
那在CMSIS(cortex microcontroller software interface standard)中是如何实现的?
首先将GPIO相关的寄存器定义为一个结构体.
typedef struct
{
__IO uint32_t CRL; //#define __IO volitile
__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 PERIPH_BASE ((uint32_t)0x40000000)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
通过以上的几个宏,现在GPIOA就是一个GPIO_TypeDef类型的结构体指针,通过它,就可以使用GPIO_TypeDef的成员,
即寄存器,每个成员都是一个4 Bytes,按照结构体的存储方式,各个成员的地址便可确定,这与数据手册给出的相对偏移
地址相对应.CRL:0x00 CRH:0x04 IDR:0x08 ODR:0x0C BSRR:0x10 BRR:0x14 LCKR:0x18
如果寄存器偏移不是连续的(不是依次差0x04),如:AFIO中,寄存器EXTICR4,MAPR2相对偏移是0x14,0x1C
此时,直接定义一个4Byte变量,跳过这个地址.
typedef struct
{
__IO uint32_t EVCR;
__IO uint32_t MAPR;
__IO uint32_t EXTICR[4];
uint32_t RESERVED0;
__IO uint32_t MAPR2; //0x1c
} AFIO_TypeDef;