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();
- }