虾仁A 2022-02-24 20:25 采纳率: 78.8%
浏览 68
已结题

野火STM32代码看了5遍不懂

问题遇到的现象和发生背景
问题相关代码,请勿粘贴截图
运行结果及报错内容

currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);是什么意思
pos = pinpos << 2;这句代码是什么意思,左移pinpos位吗?

我的解答思路和尝试过的方法
我想要达到的结果
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条回答 默认 最新

  • Mr.Sumi 2022-02-28 11:44
    关注

    涉及到的都是寄存器操作,对照着参考手册看就容易明白了。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 3月9日
  • 已采纳回答 3月1日
  • 创建了问题 2月24日

悬赏问题

  • ¥15 Python报错怎么解决
  • ¥15 simulink如何调用DLL文件
  • ¥15 关于用pyqt6的项目开发该怎么把前段后端和业务层分离
  • ¥30 线性代数的问题,我真的忘了线代的知识了
  • ¥15 有谁能够把华为matebook e 高通骁龙850刷成安卓系统,或者安装安卓系统
  • ¥188 需要修改一个工具,懂得汇编的人来。
  • ¥15 livecharts wpf piechart 属性
  • ¥20 数学建模,尽量用matlab回答,论文格式
  • ¥15 昨天挂载了一下u盘,然后拔了
  • ¥30 win from 窗口最大最小化,控件放大缩小,闪烁问题