PY32F003F18的GPIO函数

PY32F003F18的HAL_GPIO_Init()函数功能强大。

1、HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)

这个函数把将引脚配置为"输入,输出,模拟或AF辅助功能",以及外部中断中断和中断事件使能都放在里面,还包括了中断线连接。功能强大,有点难理解。

源函数:

//函数功能:根据GPIO_Init结构指针所指向的参数初始化GPIOx的外设寄存器
void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)
{
  uint32_t position = 0x00u;
  uint32_t iocurrent;
  uint32_t temp;

  /* Check the parameters */
  assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
  assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
  assert_param(IS_GPIO_PULL(GPIO_Init->Pull));

  /* Configure the port pins */
  while (((GPIO_Init->Pin) >> position) != 0x00u)
  {
    iocurrent = (GPIO_Init->Pin) & (1uL << position);
		//获取引脚位置,Get current io position

    if (iocurrent != 0x00u)//这个引脚需要配置
    {
      /*--------------------- GPIO Mode Configuration ------------------------*/
      /* In case of Alternate function mode selection */
      if ((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD))
      {//复用功能推挽模式,复用功能开漏极模式
				//将外设连接选择的引脚,Peripheral to be connected to the selected pins
        /* Check the Alternate function parameters */
        assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
        assert_param(IS_GPIO_AF(GPIO_Init->Alternate));

        /* Configure Alternate function mapped with the current IO */
        temp = GPIOx->AFR[position >> 3u];
				//当position<8时,表示GPIOx->AFR[0],读"GPIO复用功能寄存器(low)GPIOx_AFRL"
				//当position>7时,表示GPIOx->AFR[1],读"GPIO复用功能寄存器(high)GPIOx_AFRH"
        temp &= ~(0xFu << ((position & 0x07u) * 4u));//将第position个AF值清除
        temp |= ((GPIO_Init->Alternate) << ((position & 0x07u) * 4u));//修改第position个AF值
        GPIOx->AFR[position >> 3u] = temp;
				//当position<8时,表示GPIOx->AFR[0],将temp写入"GPIO复用功能寄存器(low)GPIOx_AFRL"
				//当position>7时,表示GPIOx->AFR[1],将temp写入读"GPIO复用功能寄存器(high)GPIOx_AFRH"
      }

      /* Configure IO Direction mode (Input, Output, Alternate or Analog) */
      temp = GPIOx->MODER;//读"GPIO端口模式寄存器GPIOx_MODER",x=A,B,F
      temp &= ~(GPIO_MODER_MODE0 << (position * 2u));
      temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2u));
			//GPIO_Init->Mode=00B: 输入模式
			//GPIO_Init->Mode=01B: 通用输出模式
			//GPIO_Init->Mode=10B: 复用功能模式
			//GPIO_Init->Mode=11B: 模拟模式(CPU复位时的状态)
      GPIOx->MODER = temp;//将temp写入"GPIO端口模式寄存器GPIOx_MODER",x=A,B,F

      /* In case of Output or Alternate function mode selection */
      if ((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) ||
          (GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD))
      {//推挽输出方式,输出开漏极模式,复用功能推挽模式,复用功能开漏极模式
        /* Check the Speed parameter */
        assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
        /* Configure the IO Speed */
        temp = GPIOx->OSPEEDR;//读"GPIO端口输出速度寄存器GPIOx_OSPEEDR"
        temp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2u));
        temp |= (GPIO_Init->Speed << (position * 2u));
				//GPIO_Init->Speed=00B:IO口的输出速度为非常低
				//GPIO_Init->Speed=01B:IO口的输出速度为低速
				//GPIO_Init->Speed=10B:IO口的输出速度为高速
				//GPIO_Init->Speed=11B:IO口的输出速度为非常高
        GPIOx->OSPEEDR = temp;//将temp写入"GPIO端口输出速度寄存器GPIOx_OSPEEDR"

        /* Configure the IO Output Type */
        temp = GPIOx->OTYPER;//读"GPIO端口输出类型寄存器GPIOx_OTYPER"
        temp &= ~(GPIO_OTYPER_OT0 << position) ;
        temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4u) << position);
				//GPIO_Init->Mode=0B: 推挽输出(CPU复位时的状态)
				//GPIO_Init->Mode=1B: 开漏输出
        GPIOx->OTYPER = temp;//将temp写入"GPIO端口输出类型寄存器GPIOx_OTYPER"
      }

      /* Activate the Pull-up or Pull down resistor for the current IO */
      temp = GPIOx->PUPDR;//读"GPIO 端口上下拉寄存器GPIOx_PUPDR",x=A,B,F
      temp &= ~(GPIO_PUPDR_PUPD0 << (position * 2u));
      temp |= ((GPIO_Init->Pull) << (position * 2u));
			//GPIO_Init->Pull=00B: 无上下拉
			//GPIO_Init->Pull=01B: 上拉
			//GPIO_Init->Pull=10B: 下拉
			//GPIO_Init->Pull=11B: 保留
      GPIOx->PUPDR = temp;//将temp写入"GPIO 端口上下拉寄存器GPIOx_PUPDR",x=A,B,F

      /*--------------------- EXTI Mode Configuration ------------------------*/
      /* Configure the External Interrupt or event for the current IO */
      if ((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
      {
        temp = EXTI->EXTICR[position >> 2u];//读"外部中断选择寄存器"
				//外部中断选择寄存器1(EXTI_EXTICR1)
				//外部中断选择寄存器2(EXTI_EXTICR2)
				//外部中断选择寄存器3(EXTI_EXTICR3)
        temp &= ~(0x0FuL << (8u * (position & 0x03u)));
        temp |= (GPIO_GET_INDEX(GPIOx) << (8u * (position & 0x03u)));
        EXTI->EXTICR[position >> 2u] = temp;//将temp写入"外部中断选择寄存器"

        /* Clear EXTI line configuration */
        temp = EXTI->IMR;//读"中断屏蔽寄存器EXTI_IMR"
        temp &= ~(iocurrent);//不使能引脚建立中断标志
        if ((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
        {
          temp |= iocurrent;//允许引脚在外部触发时建立中断标志
        }
        EXTI->IMR = temp;//将temp值写入"中断屏蔽寄存器EXTI_IMR"

        temp = EXTI->EMR;//读"事件屏蔽寄存器EXTI_EMR"
        temp &= ~(iocurrent);//不使能引脚建立事件标志
        if ((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
        {
          temp |= iocurrent;//允许引脚在外部触发时建立事件标志
        }
        EXTI->EMR = temp;//将temp值写入"事件屏蔽寄存器EXTI_EMR"

        /* Clear Rising Falling edge configuration */
        temp = EXTI->RTSR;//读"上升沿触发选择寄存器EXTI_RTSR"
        temp &= ~(iocurrent);
        if ((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
        {
          temp |= iocurrent;
        }
        EXTI->RTSR = temp;//将temp值写入"上升沿触发选择寄存器EXTI_RTSR"

        temp = EXTI->FTSR;//读"下降沿触发选择寄存器EXTI_FTSR"
        temp &= ~(iocurrent);
        if ((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
        {
          temp |= iocurrent;
        }
        EXTI->FTSR = temp;//将temp值写入"下降沿触发选择寄存器EXTI_FTSR"
      }
    }

    position++;
  }
}

2、函数分解:

如果把它们搬开,需要下面这几个函数才能实现其一个函数的功能。

void Configure_Alternate_function_mapped_with_Pin(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t alternate);
void Configure_Pin_Direction_mode(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t mode);
void Configure_Pin_Speed(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t speed);
void Configure_Pin_Output_Type(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t mode);
void Activate_Pull_up_or_Pull_down_for_Pin(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t pull);
void Select_External_Interrupt_Line(GPIO_TypeDef *GPIOx,uint32_t Pin);
void Set_EXTI_line_X_InterruptSwitch(uint32_t Pin,uint32_t mode);
void Set_EXTI_line_X_EventSwitch(uint32_t Pin,uint32_t mode);
void Set_Rising_And_Falling_Mode(uint32_t Pin,uint32_t mode);

#include "MyGPIO.h"

void Configure_Alternate_function_mapped_with_Pin(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t alternate);
void Configure_Pin_Direction_mode(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t mode);
void Configure_Pin_Speed(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t speed);
void Configure_Pin_Output_Type(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t mode);
void Activate_Pull_up_or_Pull_down_for_Pin(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t pull);
void Select_External_Interrupt_Line(GPIO_TypeDef *GPIOx,uint32_t Pin);
void Set_EXTI_line_X_InterruptSwitch(uint32_t Pin,uint32_t mode);
void Set_EXTI_line_X_EventSwitch(uint32_t Pin,uint32_t mode);
void Set_Rising_And_Falling_Mode(uint32_t Pin,uint32_t mode);

GPIO模式配置开始,GPIO Mode Configuration
//函数功能:当引脚配置为"AF复用功能时,需要将外设映射到引脚上
//alternate=GPIO_AF0_USART1,将引脚复用为USART1
//alternate=GPIO_AF1_USART1,将引脚复用为USART1
//alternate=GPIO_AF3_USART1,将引脚复用为USART1
//alternate=GPIO_AF3_USART2,将引脚复用为USART2
//alternate=GPIO_AF4_USART2,将引脚复用为USART2
//alternate=GPIO_AF5_USART2,将引脚复用为USART2
//alternate=GPIO_AF9_USART2,将引脚复用为USART2
void Configure_Alternate_function_mapped_with_Pin(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t alternate)
{
	uint32_t temp;
	uint32_t position;
	uint32_t iocurrent;

	position=0;
	while( (Pin >> position) != 0x00u )
	{
		iocurrent = (Pin) & (1uL << position);//获取引脚位置,Get current io position
		if(iocurrent != 0x00u)//这个引脚需要配置
		{
        temp = GPIOx->AFR[position >> 3u];
				//当position<8时,表示GPIOx->AFR[0],读"GPIO复用功能寄存器(low)GPIOx_AFRL"
				//当position>7时,表示GPIOx->AFR[1],读"GPIO复用功能寄存器(high)GPIOx_AFRH"
        temp &= ~(0xFu << ((position & 0x07u) * 4u));//将第position个AF值清除
        temp |= ( alternate << ((position & 0x07u) * 4u) );//修改第position个AF值
        GPIOx->AFR[position >> 3u] = temp;
				//当position<8时,表示GPIOx->AFR[0],将temp写入"GPIO复用功能寄存器(low)GPIOx_AFRL"
				//当position>7时,表示GPIOx->AFR[1],将temp写入读"GPIO复用功能寄存器(high)GPIOx_AFRH"
		}
		position++;
	}
}

//函数功能:将引脚配置为"输入,输出,模拟或AF辅助功能"
//mode=00B: 输入模式
//mode=01B: 通用输出模式
//mode=10B: 复用功能模式
//mode=11B: 模拟模式(CPU复位时的状态)
//mode=GPIO_MODE_INPUT,输入
//mode=GPIO_MODE_IT_RISING,输入
//mode=GPIO_MODE_IT_FALLING,输入
//mode=GPIO_MODE_IT_RISING_FALLING,输入
//mode=GPIO_MODE_EVT_RISING,输入
//mode=GPIO_MODE_EVT_FALLING,输入
//mode=GPIO_MODE_EVT_RISING_FALLING,输入
//mode=GPIO_MODE_OUTPUT_PP,输出
//mode=GPIO_MODE_OUTPUT_OD,输出
//mode=GPIO_MODE_AF_PP,AF复用功能模式
//mode=GPIO_MODE_AF_OD,AF复用功能模式
//mode=GPIO_MODE_ANALOG,模拟模式
//外部引脚边沿检测事件属于输入事件,不属于AF复用功能模式
void Configure_Pin_Direction_mode(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t mode)
{
	uint32_t temp;
	uint32_t position;
	uint32_t iocurrent;

	position=0;
	while( (Pin >> position) != 0x00u )
	{
		iocurrent = (Pin) & (1uL << position);//获取引脚位置,Get current io position
		if(iocurrent != 0x00u)//这个引脚需要配置
		{
      temp = GPIOx->MODER;//读"GPIO端口模式寄存器GPIOx_MODER",x=A,B,F
      temp &= ~(GPIO_MODER_MODE0 << (position * 2u));
      temp |= ((mode & 0x00000003) << (position * 2u));
			//mode=00B: 输入模式
			//mode=01B: 通用输出模式
			//mode=10B: 复用功能模式
			//mode=11B: 模拟模式(CPU复位时的状态)
      GPIOx->MODER = temp;//将temp写入"GPIO端口模式寄存器GPIOx_MODER",x=A,B,F
		}
		position++;
	}
}

//函数功能:在"引脚为输出或AF复用功能"时,需要配置引脚工作速度,输入和模拟不需要配置速度
//speed=GPIO_SPEED_FREQ_LOW,IO口的输出速度为非常低
//speed=GPIO_SPEED_FREQ_MEDIUM,IO口的输出速度为低速
//speed=GPIO_SPEED_FREQ_HIGH,IO口的输出速度为高速
//speed=GPIO_SPEED_FREQ_VERY_HIGH,IO口的输出速度为非常高
void Configure_Pin_Speed(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t speed)
{
	uint32_t temp;
	uint32_t position;
	uint32_t iocurrent;

	position=0;
	while( (Pin >> position) != 0x00u )
	{
		iocurrent = (Pin) & (1uL << position);//获取引脚位置,Get current io position
		if(iocurrent != 0x00u)//这个引脚需要配置
		{
			temp = GPIOx->OSPEEDR;//读"GPIO端口输出速度寄存器GPIOx_OSPEEDR"
			temp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2u));
			temp |= (speed << (position * 2u));
			//speed=00B:IO口的输出速度为非常低
			//speed=01B:IO口的输出速度为低速
			//speed=10B:IO口的输出速度为高速
			//speed=11B:IO口的输出速度为非常高
			GPIOx->OSPEEDR = temp;//将temp写入"GPIO端口输出速度寄存器GPIOx_OSPEEDR"
		}
		position++;
	}
}

//函数功能:在"引脚为输出或AF复用功能"时,需要配置"引脚输出模式",输入和模拟不需要配置速度
//mode=0B: 推挽输出(CPU复位时的状态)
//mode=1B: 开漏输出
//mode=GPIO_MODE_OUTPUT_PP,推挽输出
//mode=GPIO_MODE_OUTPUT_OD,开漏输出
//mode=GPIO_MODE_AF_PP,AF复用功能推挽输出模式
//mode=GPIO_MODE_AF_OD,AF复用功能开漏输出模式
void Configure_Pin_Output_Type(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t mode)
{
	uint32_t temp;
	uint32_t position;
	uint32_t iocurrent;

	position=0;
	while( (Pin >> position) != 0x00u )
	{
		iocurrent = (Pin) & (1uL << position);//获取引脚位置,Get current io position
		if(iocurrent != 0x00u)//这个引脚需要配置
		{
			temp = GPIOx->OTYPER;//读"GPIO端口输出类型寄存器GPIOx_OTYPER"
			temp &= ~(GPIO_OTYPER_OT0 << position) ;
			temp |= ( ( (mode & 0x00000010) >> 4u) << position );
			//mode=0B: 推挽输出(CPU复位时的状态)
			//mode=1B: 开漏输出
			GPIOx->OTYPER = temp;//将temp写入"GPIO端口输出类型寄存器GPIOx_OTYPER"
		}
		position++;
	}
}

//函数功能:输入时,可配置"无上下拉,上拉,下拉";模拟功能配置为"无上下拉"
//pull=GPIO_NOPULL: 无上下拉
//pull=GPIO_PULLUP: 上拉
//pull=GPIO_PULLDOWN: 下拉
//pull=11B: 保留
void Activate_Pull_up_or_Pull_down_for_Pin(GPIO_TypeDef *GPIOx,uint32_t Pin,uint32_t pull)
{
	uint32_t temp;
	uint32_t position;
	uint32_t iocurrent;

	position=0;
	while( (Pin >> position) != 0x00u )
	{
		iocurrent = (Pin) & (1uL << position);//获取引脚位置,Get current io position
		if(iocurrent != 0x00u)//这个引脚需要配置
		{
      temp = GPIOx->PUPDR;//读"GPIO 端口上下拉寄存器GPIOx_PUPDR",x=A,B,F
      temp &= ~(GPIO_PUPDR_PUPD0 << (position * 2u));
      temp |= ( pull << (position * 2u) );
			//pull=00B: 无上下拉
			//pull=01B: 上拉
			//pull=10B: 下拉
			//pull=11B: 保留
      GPIOx->PUPDR = temp;//将temp写入"GPIO 端口上下拉寄存器GPIOx_PUPDR",x=A,B,F
		}
		position++;
	}
}
GPIO模式配置开始,GPIO Mode Configuration

外部模式配置开始,EXTI Mode Configuration
//函数功能:连接引脚和EXTI中断线
void Select_External_Interrupt_Line(GPIO_TypeDef *GPIOx,uint32_t Pin)
{
	uint32_t temp;
	uint32_t position;
	uint32_t iocurrent;
	uint32_t port_x;

	position=0;
	while( (Pin >> position) != 0x00u )
	{
		iocurrent = (Pin) & (1uL << position);//获取引脚位置,Get current io position
		if(iocurrent != 0x00u)//这个引脚需要配置
		{
			temp = EXTI->EXTICR[position >> 2u];//读"外部中断选择寄存器"
			//外部中断选择寄存器1(EXTI_EXTICR1)
			//外部中断选择寄存器2(EXTI_EXTICR2)
			//外部中断选择寄存器3(EXTI_EXTICR3)
			temp &= ~(0x0FuL << (8u * (position & 0x03u)));
			port_x=GPIO_GET_INDEX(GPIOx);
			//当GPIOx=GPIOA,port_x=00B,映射到PA[position]引脚
			//当GPIOx=GPIOB,port_x=01B,映射到PB[position]引脚
			//当GPIOx=GPIOF,port_x=10B,映射到PF[position]引脚
			temp |= ( port_x << (8u * (position & 0x03u)));
			EXTI->EXTICR[position >> 2u] = temp;//将temp写入"外部中断选择寄存器"
		}
		position++;
	}
}

//函数功能:设置中断线x的中断开关
//mode=GPIO_MODE_IT_RISING,输入
//mode=GPIO_MODE_IT_FALLING,输入
//mode=GPIO_MODE_IT_RISING_FALLING,输入
//外部引脚边沿检测事件属于输入事件
void Set_EXTI_line_X_InterruptSwitch(uint32_t Pin,uint32_t mode)
{
	uint32_t temp;
	uint32_t position;
	uint32_t iocurrent;

	position=0;
	while( (Pin >> position) != 0x00u )
	{
		iocurrent = (Pin) & (1uL << position);//获取引脚位置,Get current io position
		if(iocurrent != 0x00u)//这个引脚需要配置
		{
			temp = EXTI->IMR;//读"中断屏蔽寄存器EXTI_IMR"
			temp &= ~(iocurrent);//不使能引脚建立中断标志
			if( (mode & 0x00010000) == 0x00010000 )
			{
				temp |= iocurrent;//允许引脚在外部触发时建立中断标志
			}
			EXTI->IMR = temp;//将temp值写入"中断屏蔽寄存器EXTI_IMR"
		}
		position++;
	}
}

//函数功能:设置中断线x的事件开关
//mode=GPIO_MODE_EVT_RISING,输入
//mode=GPIO_MODE_EVT_FALLING,输入
//mode=GPIO_MODE_EVT_RISING_FALLING,输入
//外部引脚边沿检测事件属于输入事件
void Set_EXTI_line_X_EventSwitch(uint32_t Pin,uint32_t mode)
{
	uint32_t temp;
	uint32_t position;
	uint32_t iocurrent;

	position=0;
	while( (Pin >> position) != 0x00u )
	{
		iocurrent = (Pin) & (1uL << position);//获取引脚位置,Get current io position
		if(iocurrent != 0x00u)//这个引脚需要配置
		{
			temp = EXTI->EMR;//读"事件屏蔽寄存器EXTI_EMR"
			temp &= ~(iocurrent);//不使能引脚建立事件标志
			if (( mode & 0x00020000) == 0x00020000 )
			{
				temp |= iocurrent;//允许引脚在外部触发时建立事件标志
      }
      EXTI->EMR = temp;//将temp值写入"事件屏蔽寄存器EXTI_EMR"
		}
		position++;
	}
}

//函数功能:设置引脚边沿检测模式
//mode=GPIO_MODE_IT_RISING,输入
//mode=GPIO_MODE_IT_FALLING,输入
//mode=GPIO_MODE_IT_RISING_FALLING,输入
//mode=GPIO_MODE_EVT_RISING,输入
//mode=GPIO_MODE_EVT_FALLING,输入
//mode=GPIO_MODE_EVT_RISING_FALLING,输入
//外部引脚边沿检测事件属于输入事件,不属于AF复用功能模式
void Set_Rising_And_Falling_Mode(uint32_t Pin,uint32_t mode)
{
	uint32_t temp;
	uint32_t position;
	uint32_t iocurrent;

	position=0;
	while( (Pin >> position) != 0x00u )
	{
		iocurrent = (Pin) & (1uL << position);//获取引脚位置,Get current io position
		if(iocurrent != 0x00u)//这个引脚需要配置
		{
			temp = EXTI->RTSR;//读"上升沿触发选择寄存器EXTI_RTSR"
      temp &= ~(iocurrent);
      if ((mode & 0x00100000) == 0x00100000)
      {
        temp |= iocurrent;
      }
      EXTI->RTSR = temp;//将temp值写入"上升沿触发选择寄存器EXTI_RTSR"

      temp = EXTI->FTSR;//读"下降沿触发选择寄存器EXTI_FTSR"
      temp &= ~(iocurrent);
      if ((mode & 0x00200000) == 0x00200000)
      {
        temp |= iocurrent;
      }
      EXTI->FTSR = temp;//将temp值写入"下降沿触发选择寄存器EXTI_FTSR"
		}
		position++;
	}
}
外部模式配置结束,EXTI Mode Configuration
/*
HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
//这个回调函数没啥用,用户可根据需要修改,建议不用,用了后反而不方便程序移植和管理
HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
用处不大,若"中断服务程序"需要调用该函数,就需要修改HAL_GPIO_EXTI_Callback()

设置中断源的中断优先级:
NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
将IRQn中断源的中断优先级设置为priority
HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
它是通过调用NVIC_SetPriority()来实现的
将IRQn中断源的中断优先级设置为PreemptPriority,SubPriority在程序中不使用
0<=PreemptPriority<=3,值越大,表示中断优先级越低

允许中断源产生中断:
NVIC_EnableIRQ(IRQn_Type IRQn)
允许中断源IRQn在中断标志建立时能够产生中断
HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
它是通过调用NVIC_EnableIRQ()来实现的
允许中断源IRQn在中断标志建立时能够产生中断

不允许中断源产生中断:
NVIC_DisableIRQ(IRQn_Type IRQn)
不允许中断源IRQn在中断标志建立时能够产生中断
HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
它是通过调用NVIC_DisableIRQ()来实现的
不允许中断源IRQn在中断标志建立时能够产生中断

读取中断源的中断标志位:
NVIC_GetPendingIRQ(IRQn_Type IRQn)
读取IRQn中断源的中断标志位

将中断源的中断标志位置位:
NVIC_SetPendingIRQ(IRQn_Type IRQn)
将IRQn中断源的中断标志位置1,使其产生中断

清除中断源的中断标志位:
NVIC_ClearPendingIRQ(IRQn_Type IRQn)
//清除IRQn中断源的中断标志位,使其不产生中断

清除事件标志位:
__HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_X)和__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_X)
这两个功能相同
根据GPIO_PIN_x,清除"外部中断挂起寄存器EXTI_PR中的PRx位",
取消引脚产生的上升沿,下降沿或软件触发产生事件标志位;
清除事件标志位

读事件标志位:
__HAL_GPIO_EXTI_GET_FLAG(GPIO_PIN_X)和__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_X)
这两个功能相同
读"GPIO_PIN_X外部中断线建立的事件标志位"

在某个外部中断线上上升沿触发事件:
__HAL_GPIO_EXTI_GENERATE_SWIT(GPIO_PIN_X)
根据GPIO_PIN_x,将"外部软件中断事件寄存器EXTI_SWIER中的SWx位"置1,
使其产生EXTI line_x上升沿触发事件,进而产生中断,该位由硬件清零;

普通GPIO功能:
__HAL_RCC_GPIOA_CLK_ENABLE();//使能GPIOA时钟
__HAL_RCC_GPIOB_CLK_ENABLE();//使能GPIOB时钟
__HAL_RCC_GPIOF_CLK_ENABLE();//使能GPIOF时钟
HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)
根据GPIO_InitTypeDef型结构变量指定的参数初始化GPIOx的外设寄存器
HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
PinState=0,GPIOx端口的GPIO_Pin引脚输出低电平;PinState=1,GPIOx端口的GPIO_Pin引脚输出高电平
HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
GPIOx端口的GPIO_Pin的输出电平翻转
HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
读取"GPIOx端口的第GPIO_Pin引脚"输入的电平值
HAL_GPIO_DeInit(GPIO_TypeDef  *GPIOx, uint32_t GPIO_Pin)
将"GPIOx端口的GPIO_Pin引脚"的外设寄存器恢复到"复位时的默认值"

HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
锁定GPIO引脚GPIO_Pin的配置;当GPIO_Pin执行了"锁键的写入时序"后,在下次系统复位前将不能再更改端口位的配置;
//这个回调函数没啥用
*/

3、经过测试,可以使用

#include "LED.h"
#include "MyGPIO.h"

void MCU_LED_Init(void);

//函数功能:MCU_LED灯引脚初始化,并配置为关灯
void MCU_LED_Init(void)
{
/*
  GPIO_InitTypeDef  GPIO_InitStructure;

  __HAL_RCC_GPIOB_CLK_ENABLE();//使能GPIOB时钟

  //初始化GPIOB5
  GPIO_InitStructure.Pin = GPIO_PIN_5;                  //选择第5脚
  GPIO_InitStructure.Pull = GPIO_PULLUP;                //引脚上拉被激活
  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //配置GPIO速度为极高
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;        //设置引脚工作模式为推挽输出方式

  HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
	//根据GPIO_InitStructure结构变量指定的参数初始化GPIOB的外设寄存器
*/

	__HAL_RCC_GPIOB_CLK_ENABLE();//使能GPIOB时钟
	Configure_Pin_Direction_mode(GPIOB,GPIO_PIN_5,GPIO_MODE_OUTPUT_PP);
	Activate_Pull_up_or_Pull_down_for_Pin(GPIOB,GPIO_PIN_5,GPIO_PULLUP);

	MCU_LED_Off();
}

你可能感兴趣的:(产品研发,PY32F003F18,普冉,嵌入式硬件,单片机,GPIO)