首先,我们可以看见GPIO.c源文件。
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{
uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
uint32_t tmpreg = 0x00, pinmask = 0x00;
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
根据头文件,形参1 定义GPIOx为GPIO_TypeDef* 型,指针变量,只能是有效的指针和地址,形参2 定义GPIO_InitStruct为GPIO_InitTypeDef* 型,指针变量,也只能是有效的指针和地址.
当初始化设定GPIO口时,在STM32103x.h头文件中,已经定义了输入形参1的定义,所以形参1在初始化函数里不需要取地址符号,因为操作GPIOA等就是指针。
#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)
而当定义GPIO的初始化设置类型时,形参2 比如定义为 GPIO_InitTypeDef GPIO_InitStructure,定义GPIO_InitStructure为GPIO_InitTypeDef 结构体类型,而不是GPIO_InitTypeDef* 。形参是指针类型,只能是指针和地址,而实参是GPIO_InitTypeDef 结构体类型,所以需要对实参进行取地址操作。所以要写成GPIO_Init(GPIOx, &GPIO_InitStructure)。
比如如下定义是可行的。定义成指针类型的,那么结构体变量就是(* GPIO_InitStructure),GPIO_InitStructure则是指针变量。
GPIO_InitTypeDef* GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//GPIOB
(*GPIO_InitStructure).GPIO_Mode=GPIO_Mode_Out_PP;
(*GPIO_InitStructure).GPIO_Pin=GPIO_Pin_5;
(*GPIO_InitStructure).GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_5);
根据习惯方便,定义GPIO_InitTypeDef GPIO_InitStructure,则就需要写成GPIO_Init(GPIOx, &GPIO_InitStructure)。