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日

悬赏问题

  • ¥20 双层网络上信息-疾病传播
  • ¥50 paddlepaddle pinn
  • ¥15 Stata 面板数据模型选择
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 请问这个是什么意思?
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏