栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

STM32标准库与HAL库中的Mode和Pull设置

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

STM32标准库与HAL库中的Mode和Pull设置

目录

概述HAL库标准库再看HAL库

概述

最近做SDK的BSP驱动。之前使用STM32CubeMX进行开发,设计GPIO的初始化接口包括了mode、pull两个参数。
现在对接另一款国产芯片,芯片驱动仅支持标准库,在GPIO的初始化结构体中没有pull成员,且mode也不完全相同。那么该如何处理这两个参数呢?

HAL库

先看下STM32L152CCTx的工程,GPIO的初始化函数中对于pull的处理:

void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)
{

      
      temp = GPIOx->PUPDR;
      CLEAR_BIT(temp, GPIO_PUPDR_PUPDR0 << (position * 2));
      SET_BIT(temp, (GPIO_Init->Pull) << (position * 2));
      GPIOx->PUPDR = temp;
      
}

也就是操作PUPDR寄存器,查看手册定义如下:

而支持的mode如下:

#define  GPIO_MODE_INPUT                        (0x00000000U)   
#define  GPIO_MODE_OUTPUT_PP                    (0x00000001U)   
#define  GPIO_MODE_OUTPUT_OD                    (0x00000011U)   
#define  GPIO_MODE_AF_PP                        (0x00000002U)   
#define  GPIO_MODE_AF_OD                        (0x00000012U)   

#define  GPIO_MODE_ANALOG                       (0x00000003U)   
标准库

现在看下标准库时如何初始化的。标准库直接参考STM32F103的工程,GPIO初始化函数的主要代码如下:

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{


  currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
  if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
  { 
    
    assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
    
    currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
  }

  
  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;
      
      currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
      if (currentpin == pos)
      {
        pos = pinpos << 2;
        
        pinmask = ((uint32_t)0x0F) << pos;
        tmpreg &= ~pinmask;
        
        tmpreg |= (currentmode << pos);
        
        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
        {
          GPIOx->BRR = (((uint32_t)0x01) << pinpos);
        }
        else
        {
          
          if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
          {
            GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
          }
        }
      }
    }
    GPIOx->CRL = tmpreg;
  }
  
}
    获取模式的低四位,得到mode。若为输出,则一并设置 speed;根据上拉还是下拉,管脚输出对应电平。

从代码可以看出,只有输入才会有上下拉。而支持的mode如下:

typedef enum
{ GPIO_Mode_AIN = 0x0,
  GPIO_Mode_IN_FLOATING = 0x04,
  GPIO_Mode_IPD = 0x28,
  GPIO_Mode_IPU = 0x48,
  GPIO_Mode_Out_OD = 0x14,
  GPIO_Mode_Out_PP = 0x10,
  GPIO_Mode_AF_OD = 0x1C,
  GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;

与HAL库相比,多了GPIO_Mode_IPD和GPIO_Mode_IPU。也就是HAL库需要设置为输入模式,再单独设置上拉、下拉、浮空,而标准库直接定义了上拉输入模式、下拉输入模式和浮空输入模式。

另外,每个pin的模式由4bit控制,为什么枚举采用8bit呢?
这一点从代码中也可以看出来,高四位的0x1表示输出。

再看HAL库

查看STM32F103参考手册,也并没有PUPDR寄存器,应该是不同内核的原因。
用STM32CubeMX生成一个STM32F103的HAL库版本,查看下HAL库是如何处理的。生成后直接定位到HAL_GPIO_Init函数:

可以看到同样是对寄存器的4bit进行设置。展开switch,可以看到对Pull的处理,也就是先判断mode。如果为输入,则继续判断pull,最终还是归纳到标准库支持的8个mode:

到这里,SDK该如何处理mode和pull参数也就清晰了。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/767481.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号