STM32标准库与HAL库中的Mode和Pull设置
Posted 何事误红尘
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32标准库与HAL库中的Mode和Pull设置相关的知识,希望对你有一定的参考价值。
目录
概述
最近做SDK的BSP驱动。之前使用STM32CubeMX进行开发,设计GPIO的初始化接口包括了mode、pull两个参数。
现在对接另一款国产芯片,芯片驱动仅支持标准库,在GPIO的初始化结构体中没有pull成员,且mode也不完全相同。那么该如何处理这两个参数呢?
HAL库
先看下STM32L152CCTx的工程,GPIO的初始化函数中对于pull的处理:
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
/* Activate the Pull-up or Pull down resistor for the current IO */
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) /*!< Input Floating Mode */
#define GPIO_MODE_OUTPUT_PP (0x00000001U) /*!< Output Push Pull Mode */
#define GPIO_MODE_OUTPUT_OD (0x00000011U) /*!< Output Open Drain Mode */
#define GPIO_MODE_AF_PP (0x00000002U) /*!< Alternate Function Push Pull Mode */
#define GPIO_MODE_AF_OD (0x00000012U) /*!< Alternate Function Open Drain Mode */
#define GPIO_MODE_ANALOG (0x00000003U) /*!< Analog Mode */
标准库
现在看下标准库时如何初始化的。标准库直接参考STM32F103的工程,GPIO初始化函数的主要代码如下:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
/*---------------------------- GPIO Mode Configuration -----------------------*/
currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
/* Check the parameters */
assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
/* Output mode */
currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
/*---------------------------- GPIO CRL Configuration ------------------------*/
/* Configure the eight low port pins */
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;
/* Get the port pins position */
currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
if (currentpin == pos)
pos = pinpos << 2;
/* Clear the corresponding low control register bits */
pinmask = ((uint32_t)0x0F) << pos;
tmpreg &= ~pinmask;
/* Write the mode configuration in the corresponding bits */
tmpreg |= (currentmode << pos);
/* Reset the corresponding ODR bit */
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
GPIOx->BRR = (((uint32_t)0x01) << pinpos);
else
/* Set the corresponding ODR bit */
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参数也就清晰了。
以上是关于STM32标准库与HAL库中的Mode和Pull设置的主要内容,如果未能解决你的问题,请参考以下文章
STM32标准库与HAL库对照学习教程外设篇--红外避障传感器
STM32标准库与HAL库对照学习教程特别篇--IIC通信原理讲解
STM32实现光照强度传感器(BH1750)(标准库与HAL库实现)
STM32实现光照强度传感器(BH1750)(标准库与HAL库实现)