STM32—HAL库中GPIO相关函数解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014470361/article/details/78959028

背景:

最近一直在学习HAL库,总结下STM32中HAL库的GPIO相关函数知识点。

内容:

在stm32l152xb.h头文件中定义了GPIO的相关寄存器,下面讲述的GPIO函数将会调用到这些寄存器。寄存器的结构体定义如下图:

下面解析stm32l1xx_hal_gpio.c文件中一些常用的GPIO函数:

(1)GPIO_PinState     HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)函数

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  GPIO_PinState bitstatus;


  /* Check the parameters */
  assert_param(IS_GPIO_PIN(GPIO_Pin));//检查确认是不是GPIO口,从GPIO_PIN_0到GPIO_PIN_ALL


  if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)  //判断输入数据寄存器是不是GPIO_PIN_SET
  {
    bitstatus = GPIO_PIN_SET;
  }
  else
  {
    bitstatus = GPIO_PIN_RESET;
  }
  return bitstatus;
}

(2)void              HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) 函数

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
  /* Check the parameters */
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  assert_param(IS_GPIO_PIN_ACTION(PinState));

  if (PinState != GPIO_PIN_RESET)
  {
    GPIOx->BSRR = (uint32_t)GPIO_Pin;//如果是GPIO_PIN_SET,则将GPIO的BSRR寄存器低16位置为GPIO_Pin
  }
  else
  {
    GPIOx->BSRR = (uint32_t)GPIO_Pin << 16 ;//如果是GPIO_PIN_RESET,则将GPIO的BSRR寄存器的高16位置为GPIO_Pin
  }
}

例如函数输入的参数是GPIOA、GPIO_Pin_1和GPIO_PIN_SET,则GPIOA->BSRR=((uint32_t)0x0002U);即把二进制数0000000000000010转换为32位数赋值给BSRR,对应的GPIO_Pin_1管脚置高;

例如函数输入的参数是GPIOA、GPIO_Pin_1和GPIO_PIN_RESET,则GPIOA->BSRR=((uint32_t)0x0002U<<16);即把二进制数0000000000000010左移16位并转换为32位数赋值给BSRR,高16位对应的GPIO_Pin_1为1,对应管脚被清零,置低;

(3)void              HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)函数

void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_PIN(GPIO_Pin));

  GPIOx->ODR ^= GPIO_Pin;//输出数据寄存器与GPIO_Pin异或;
}

例如函数的输入参数是GPIOA、GPIO_Pin_1,则GPIOx->ODR与0000000000000010进行异或操作,0 ^ 1 =1,1 ^ 1 =0,异或运算后,原来的对应位被翻转。

(4)void              HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);函数

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) //若中断标志被置位
  { 
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);//清楚标志位
    HAL_GPIO_EXTI_Callback(GPIO_Pin);//进入回调函数
  }
}

(5)void              HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);函数

__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

//_weak:__weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,那么编译器就会执行__weak 声明的函数,并且编译器不会报错。
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);//防止出现警告,#define UNUSED(x)  ((void)(x)),x前面用void定义时,可以避免x定义了但没调用的错误


  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_GPIO_EXTI_Callback could be implemented in the user file
   */ 
}

猜你喜欢

转载自blog.csdn.net/u014470361/article/details/78959028