×
单片机 > 单片机程序设计 > 详情

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

发布时间:2020-06-01 发布时间:
|

背景:

最近一直在学习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

   */ 

}

 


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机制作超级流水灯