GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); 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_InitTypeDef GPIO_InitStructure;是一个结构体变量的声明。
结构体是一种集合,它里面包含了多个变量或数组,它们的类型能够相同,也能够不一样,每一个这样的变量或数组都称为结构体的成员(Member)。
定义通常形式以下:
struct 结构类型名
{
数据类型 成员名 1;
数据类型 成员名 2;
…
数据类型 成员名 n;
};
结构变量声明的通常形式以下:
struct 结构类型名称 结构变量名; (代表这个变量名的结构类型是上面这个类型。)
也能够在定义结构体的同时定义结构体变量
struct 结构类型名
{
数据类型 成员名 1;
数据类型 成员名 2;
…
数据类型 成员名 n;
}stu1,stu2;
跳转到GPIO_InitTypeDef 的定义上,发现web
typedef struct { uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. This parameter can be any value of @ref GPIO_pins_define */ GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. This parameter can be a value of @ref GPIOSpeed_TypeDef */ GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. This parameter can be a value of @ref GPIOMode_TypeDef */ }GPIO_InitTypeDef;
这个结构体定义了GPIO_Pin,GPIO_Speed和 GPIO_Speed( GPIO_Speed和GPIO_Speed 也是结构体)
在GPIO_InitTypeDef GPIO_InitStructure;
这句话的理解是咱们定义一个结构体GPIO_InitStructure,他的成员有GPIO_Pin,GPIO_Speed和 GPIO_Speed。数组
结构体成员的引用有
变量名.成员名
例:GPIO_InitStructure.GPIO_Mode
变量名->成员名
例:GPIO_InitStructure->GPIO_Modesvg
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
它的意思是将GPIO_Mode_Out_PP(跳转到GPIO_Mode_Out_PP发现GPIO_Mode_Out_PP=0x10)赋值给GPIO_InitStructure.GPIO_Mode;将GPIO_Pin_5赋值给GPIO_InitStructure.GPIO_Pin;将GPIO_Speed_50MHz赋值给GPIO_InitStructure.GPIO_Speed。函数
这句话的意思是按照GPIO_Init()这个函数的规则来初始化GPIO口。跳转到GPIO_Init这个函数.这里面写了是如何对寄存器进行操做,而后设置各个GPIO口。ui
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)); /*---------------------------- GPIO Mode Configuration -----------------------*/ currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F); if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)//判断是否为输出模式,若是是输出模式 则要设置输出速率 { /* Check the parameters */ assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); /* Output mode */ currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed; } /*---------------------------- GPIO CRL Configuration ------------------------*/ /* Configure the eight low port pins */ if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00) { tmpreg = GPIOx->CRL; for (pinpos = 0x00; pinpos < 0x08; pinpos++) { pos = ((uint32_t)0x01) << pinpos; /* Get the port pins position */ currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; if (currentpin == pos) { pos = pinpos << 2; /* Clear the corresponding low control register bits */ pinmask = ((uint32_t)0x0F) << pos; tmpreg &= ~pinmask; /* Write the mode configuration in the corresponding bits */ tmpreg |= (currentmode << pos); /* Reset the corresponding ODR bit */ if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD) { GPIOx->BRR = (((uint32_t)0x01) << pinpos); } else { /* Set the corresponding ODR bit */ if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU) { GPIOx->BSRR = (((uint32_t)0x01) << pinpos); } } } } GPIOx->CRL = tmpreg; } /*---------------------------- GPIO CRH Configuration ------------------------*/ /* Configure the eight high port pins */ if (GPIO_InitStruct->GPIO_Pin > 0x00FF) { tmpreg = GPIOx->CRH; for (pinpos = 0x00; pinpos < 0x08; pinpos++) { pos = (((uint32_t)0x01) << (pinpos + 0x08)); /* Get the port pins position */ currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos); if (currentpin == pos) { pos = pinpos << 2; /* Clear the corresponding high control register bits */ pinmask = ((uint32_t)0x0F) << pos; tmpreg &= ~pinmask; /* Write the mode configuration in the corresponding bits */ tmpreg |= (currentmode << pos); /* Reset the corresponding ODR bit */ if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD) { GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08)); } /* Set the corresponding ODR bit */ if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU) { GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08)); } } } GPIOx->CRH = tmpreg; } } /** * @brief Fills each GPIO_InitStruct member with its default value. * @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will * be initialized. * @retval None */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));的做用就是检测传递给IS_GPIO_ALL_PERIPH函数的参数是不是有效的参数。IS_GPIO_ALL_PERIPH函数的定义是:code
#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ ((PERIPH) == GPIOB) || \ ((PERIPH) == GPIOC) || \ ((PERIPH) == GPIOD) || \ ((PERIPH) == GPIOE) || \ ((PERIPH) == GPIOF) || \ ((PERIPH) == GPIOG))
这代表IS_GPIO_ALL_PERIPH的函数只能是GPIOABCDEFG的一个。若是不是其中的一个,函数无效。xml