关于使用固件库操作GPIO管脚,在配置时,使用了这样的语句:
GPIOx->BRR = GPIO_Pin;
固件库相关源码:
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)
#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)
#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)
#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)
查得GPIOA_BASE为地址值GPIOA_BASE= 0x40000000+0x10000+0x0800=0x40010800
那么一个地址值被强制转化为GPIO_TypeDef类型指针GPIOA ,GPIOA的地址与首地址相同,此时为GPIOA_BASE,
是一个寄存器的地址值。考虑到是个GPIOA结构体类型指针,那么想象分配内存时(定义结构体变量时才有分配)使用对齐方式分配连续的地址,
那么GPIOA->CRH的地址值为GPIOA_BASE+4;
好的,现在回顾操作寄存器时是用这样的语句*GPIOA_BASE = XXXX(表示对寄存器指向的存储空间赋值);
我们现在就可以来理解GPIOx->BRR = GPIO_Pin;
可以理解成*(&GPIOX->BRR)= XXX(即GPIO_Pin);往GPIOX->BRR的地址所指向的空间赋值;
验证方式:
可以用MDK 软件调试把GPIOx->BRR的地址值打印出来看看;
具体的方法可以参考网上的资料。
验证方式:2
stm32f10x_rcc.c里有这样的函数
void RCC_PLLCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
*(__IO uint32_t *) CR_PLLON_BB = (uint32_t)NewState; //注意这里*(__IO uint32_t *) CR_PLLON_BB = 。。。
}