STM32CubeMX的EXTI(外部中断)接口使用注意事项

最近移植一个项目使用STM32F030,使用CubeMX中生成的代码,审查代码时候,看起来总有些疑惑。
关于外部中断使能的函数不见了,查找到中断使能,只有这两句话。
这样在哪设置边沿触发呢???使能了EXIT0和EXIT1的中断,但是我只需要EXIT0,这又是怎么对应的呢???

static void MX_NVIC_Init(void)
{
  /* EXTI0_1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(EXTI0_1_IRQn, 3, 0);
  HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
}

首先看一下手册,相关寄存器在这里插入图片描述
在这里插入图片描述

标准库中,初始化一个外部中断,需要先配置中断,在使能中断。如下EXTI_Init,和NVIC_Init。


//外部中断初始化函数
void EXTIX_Init(void)
{
 	EXTI_InitTypeDef EXTI_InitStructure;
 	NVIC_InitTypeDef NVIC_InitStructure;
  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使能AFIO时钟
  	
    //GPIOA.0	  中断线以及中断初始化配置
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);

   	EXTI_InitStructure.EXTI_Line=EXTI_Line0;
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_Init(&EXTI_InitStructure);		//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
  	
  	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			//使能按键所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;					//子优先级
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure);  	  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}

下意识地就去找EXTI_Init对应的HAL函数,还真有HAL_EXTI_SetConfigLine,里面有RTSR,FTSR,IMR,EMR相关寄存器的操作,然后以为是这样写,但始终觉得不妥。

//外部中断初始化函数
void EXTIX_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct; 
	EXTI_ConfigTypeDef EXTI_InitStruct;

	EXTI_InitStruct.Line = EXTI_LINE_0;
	EXTI_InitStruct.Mode = EXTI_MODE_INTERRUPT;
	EXTI_InitStruct.Trigger = EXTI_TRIGGER_RISING_FALLING; //下降沿中断
	EXTI_InitStruct.GPIOSel = EXTI_GPIOA;
	HAL_EXTI_SetConfigLine(&hexti0,&EXTI_InitStruct); 
	
  /* EXTI0_1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(EXTI0_1_IRQn, 3, 0);
  HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
}

然后仔细看了GPIO初始化函数,才发现MX是怎么处理的。

  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
                          |GPIO_PIN_8|GPIO_PIN_11;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;//中断配置
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

Mode = GPIO_MODE_IT_RISING,在这里做出了区别,有点隐蔽啊。
然后跳到HAL_GPIO_Init去看,的确在这里对外部中断寄存器做出配置。
在这里插入图片描述
使用哪种方法看个人,甚至直接寄存器,完工。

附上中断函数,
这里之前出错了,不能用if(__HAL_GPIO_EXTI_GET_IT(EXTI_LINE_0) != 0x00u),而是if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != 0x00u)。
区别如下,__HAL_GPIO_EXTI_GET_IT是读取PR寄存器,GPIO_PIN_0产生中断PR=0x0001,使用EXTI_LINE_0是错误的。

#define EXTI_LINE_0 (EXTI_GPIO | 0x00u) /*!< External interrupt line 0 /
#define GPIO_PIN_0 ((uint16_t)0x0001U) /
Pin 0 selected */

void EXTI0_1_IRQHandler(void)
{
	if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != 0x00u)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);
		
  }
	else if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_1) != 0x00u)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);
		
  }
}

或者使用回调函数,在HAL_GPIO_EXTI_Callback写需要的功能

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Prevent unused argument(s) compilation warning */
  //UNUSED(GPIO_Pin);

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

下面的回调过程简单看一下,自己写了HAL_GPIO_EXTI_Callback系统的就会屏蔽编译。

void EXTI0_1_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_1_IRQn 0 */

  /* USER CODE END EXTI0_1_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
  /* USER CODE BEGIN EXTI0_1_IRQn 1 */

  /* USER CODE END EXTI0_1_IRQn 1 */
}
/**
  * @brief  Handle EXTI interrupt request.
  * @param  GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
  * @retval None
  */
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
  { 
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}

/**
  * @brief  EXTI line detection callback.
  * @param  GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
  * @retval None
  */
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);

  /* NOTE: This function should not be modified, when the callback is needed,
            the HAL_GPIO_EXTI_Callback could be implemented in the user file
   */ 
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值