weixin_50697999 2022-08-09 22:18 采纳率: 73.7%
浏览 28
已结题

stm32f103库函数GPIO_Init里的一个语句

currentpin=(GPIO_InitStruct->GPIO_Pin)&pos;
这个语句具体有啥作用?
后面直接用GPIO_InitStruct->GPIO_Pin==pos判断不就行了吗?

  • 写回答

2条回答 默认 最新

  • CSDN专家-sinJack 2022-08-09 22:45
    关注
    // 令pos与输入参数GPIO_PIN作位与运算,为下面的判断作准备
    currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
    
    
    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 模式配置 --------------------------*/
        // 把输入参数GPIO_Mode的低四位暂存在currentmode
        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)
                  {
                        //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 + 0x08));
                        }
                        // 判断是否为上拉输入模式
                        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
                        {
                              // 上拉输入模式,引脚默认值为1,对BSRR寄存器写1可对引脚置1
                              GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
                        }
                  }
            }
            // 把前面处理后的暂存值写入到CRH寄存器之中
            GPIOx->CRH = tmpreg;
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 8月18日
  • 已采纳回答 8月10日
  • 创建了问题 8月9日

悬赏问题

  • ¥15 centos7.9脚本,怎么排除特定的访问记录
  • ¥15 关于#Django#的问题:我的静态文件呢?
  • ¥15 关于CPLEX的问题,请专家解答
  • ¥15 cocos的点击事件 怎么穿透到 原生fragment上。
  • ¥20 基于相关估计的TDOA算法中的加权最小二乘拟合法matlab仿真
  • ¥20 基于相关估计的TDOA算法中的自适应加权广义互相关法。
  • ¥15 abaqus CAE 2024软件启动问题
  • ¥20 基于相关估计的TDOA算法中的局部互相关函数滤波matlab仿真
  • ¥15 CDH6.0.1 hue报错
  • ¥15 javaFX利用scene builder的fxml文件进行开发时的label setText方法未生效问题