初始化结构体:

typedef struct
 {
   uint16_t GPIO_Pin;
     uint16_t GPIO_Speed;
     uint16_t GPIO_Mode;
 }GPIO_InitTypeDef;

里面有端口、模式和输出模式时的最大速度

再通过两个枚举类型的结构体来选择Mode和Speed

ANdroid gpio 目录 gpio_initstructure.gpio_寄存器

 

定义一个 GPIO_InitTypeDef的分支

GPIO_InitTypeDef  GPIO_InitStructure;
选择 GPIO_InitStructure的成员的端口、模式、速度
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
     GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
     GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHZ;再通过 GPIO_Init 函数来实现GPIO 模式配置,即
  GPIO_Init(GPIOB,&GPIO_InitStructure);
******************************************************************************************************
野火视频里的GPIO_Init函数
******************************************************************************************************
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; 
 /*---------------------------- GPIO 模式配置 -----------------------*/
   currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
     // bit4是1表示输出,bit4是0则是输入
     //判断bit4是1还是0,即首选判断是输入还是输出模式
   if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
   { 
     //输出模式则要设置输出速度
     currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
   }
 /*一—-------—---GPIO CRL寄存器配置CRL寄存器控制着低8位IO- -------*/
     //配置端口低8位,即Pin0~Pin7
   if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
   {
         //先备份CRL寄存器的值
     tmpreg = GPIOx->CRL;
         //循环,从Pin0开始配对,找出具体的Pin
     for (pinpos = 0x00; pinpos < 0x08; pinpos++)
     {
              // pos的值为1左移pinpos位
       pos = ((uint32_t)0x01) << pinpos;
        //令pos与输入参数GPIo_PIN作位与运算,为下面的判断作准备
       currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
             //若currentpin=pos,则找到使用的引脚
       if (currentpin == pos)
       {
             // pinpos的值左移两位(乘以4),因为寄存器中4个寄存器位配置一个引脚
         pos = pinpos << 2;
        //把控制这个引脚的4个寄存器位清零,其它寄存器位不变
         pinmask = ((uint32_t)0x0F) << pos;
         tmpreg &= ~pinmask;
        //向寄存器写入将要配置的引脚的模式
         tmpreg |= (currentmode << pos);
        //判断是否为下拉输入模式
         if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
         {
                     //下拉输入模式,引脚默认置0,对BRR寄存器写1可对引脚置0
           GPIOx->BRR = (((uint32_t)0x01) << pinpos);
         }
         else
         {
          //判断是否为上拉输入模式
           if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
           {
                         //上拉输入模式,引脚默认值为1,对BSRR寄存器写1可对引脚置1
             GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
           }
         }
       }
     }
         //把前面处理后的暂存值写入到cRL寄存器之中
     GPIOx->CRL = tmpreg;
   }
 /*-------------GPIo CRH寄存器配置CRH寄存器控制着高8位IO-----------*/
     //配置端口高8位,即Pin8~Pin15
   if (GPIO_InitStruct->GPIO_Pin > 0x00FF)
   {
         //先备份CRH寄存器的值
     tmpreg = GPIOx->CRH;
         
         //循环,从Pin8开始配对,找出具体的Pin
     for (pinpos = 0x00; pinpos < 0x08; pinpos++)
     {
       pos = (((uint32_t)0x01) << (pinpos + 0x08));
       //pos与输入参数GPIO_PIN作位与运算
       currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
             //若currentpin=pos,则找到使用的引脚
       if (currentpin == pos)
       {
         pos = pinpos << 2;
         //把控制这个引脚的4个寄存器位清零,其它寄存器位不变
         pinmask = ((uint32_t)0x0F) << pos;
         tmpreg &= ~pinmask;
         //向寄存器写入将要配置的引脚的模式
         tmpreg |= (currentmode << pos);
         //判断是否为下拉输入模式
         if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
         {
                     //下拉输入模式,引脚默认置0,对BRR寄存器写1可对引脚置
           GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
         }
        //判断是否为上拉输入模式
         if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
         {
                     //上拉输入模式,引脚默认值为1,对BSRR寄存器写1可对引脚置1
           GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
         }
       }
     }
       //把前面处理后的暂存值写入到CRH寄存器之中
     GPIOx->CRH = tmpreg;
   }
 }