STM32 LL库中断配置引脚外部中断的方式

电子说

1.3w人已加入

描述

中断原理图

GPIO

GPIO

GPIO

GPIO

很多情况可以产生中断,开发者可以在CubeMx中NVIC选单、通讯模块选单处配置。请自行探索;部分中断有关的内容在模块讲解时·将会提到。

※启用中断后,注意在System Core->NVIC->Code Generation中勾选生成IRQ Handler和 Select for init Sequence Ordering。

※生成的中断函数定义在stm32fxxx_it.h和stm32fxxx_it.c中,向函数中填要执行的代码即可。

对于外部中断的事件分配,多个引脚将被分配到中断事件(具体可以参考文档),若需要区分则须在中断程序内写判断。判断方式之后给到

配置引脚外部中断的方式:

①在引脚图上选中需要配置的引脚,选择中断功能(如图)

GPIO

②在NVIC选单中使能中断

GPIO

③在NVIC->Code Generation中勾选生成IRQ Handler和 Select for init Sequence

GPIO

勾选Select for init Sequence是个人习惯,这样可以在main.c中生成独立初始化函数

④在GPIO->GPIO配置中断模式(如图)

GPIO

可以配置上/下拉电阻(上拉、下拉、浮空)和中断触发模式。

⑤生成代码。(stm32fxxx_it.c中,配置为Interrupt Mode)

void EXTI15_10_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI15_10_IRQn 0 */

  /* USER CODE END EXTI15_10_IRQn 0 */
  /* USER CODE BEGIN EXTI15_10_IRQn 1 */

  /* USER CODE END EXTI15_10_IRQn 1 */
}

外部触发类型与中断处理:

一、触发类型

上升沿触发、下降沿触发、上升/下降沿触发(电平变化触发)

二、中断处理※

分为中断模式(Interrupt Mode)事件模式(Event Mode) 两种

中断模式即为普通中断,其概念不多解释。配置成中断模式时,stm32fxxx_it库中会自动生成中断句柄函数。

事件模式 。(很少用)

参考本文最前面提供的中断原理图。在配置为事件模式时,中断信号将传输给图中的Pulse Generator而非中断控制器。

虽然中断和事件的硬件信号产生源相同,但是配置为事件时将不会发生挂起,也就是说事件过程不需CPU的参与,可以与主程序并行: 事件机制提供了一个完全由硬件自动完成的触发到产生结果的通道,不要软件的参与,降低了CPU的负荷,节省了中断资源,提高了响应速度(硬件总快于软件)。

※事件模式虽然有优势,但在实际工程中几乎不会有人使用。不讲了。之后的代码默认使用中断模式配置。

配置外部中断需要三步: 1.配置GPIO与中断线(Input Line)连接 2.中断线配置 3.中断向量配置

结合代码:

Pin:PC13
Mode:Interrupt; Rising edge Trigger detection
Pull: Floating

在gpio.c :

/*连接引脚与中断线(EXTICRn)*/
  LL_GPIO_AF_SetEXTISource(LL_GPIO_AF_EXTI_PORTC, LL_GPIO_AF_EXTI_LINE13);

  /*配置中断线*/
  EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_13;  //配置触发源的连接
  EXTI_InitStruct.LineCommand = ENABLE;
  EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
  EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING;
  LL_EXTI_Init(&EXTI_InitStruct);

  /*引脚GPIO设置*/
  LL_GPIO_SetPinMode(GPIOC, LL_GPIO_PIN_13, LL_GPIO_MODE_FLOATING);
  
  /* EXTI interrupt init*/
  NVIC_SetPriority(EXTI15_10_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),1, 0));
  NVIC_EnableIRQ(EXTI15_10_IRQn);

※关于LL_EXTI_LINE_x:

x代表的是中断线;中断线(LINEx) 是中断信号的输入硬件。

GPIO

Line连接GPIO,例如LINE13可接PA13、PB13、PC13....。可以将引脚与中断线理解为短接。中断线同时只能连接一个引脚(LINEx只能连接PAx,PBx,PCx,PDx...其一)。 来自Input Line的信号输入触发中断程序的调用

※中断程序结束时别忘清除中断位挂起位

LL API分析:

Input Line引脚输入配置

stm32fxxx_ll_gpio.h中:

/**/
__STATIC_INLINE void LL_GPIO_AF_SetEXTISource(uint32_t Port, uint32_t Line);/*
使能中断引脚 Pnx;通过此函数将使引脚连接相应的EXTI_LINE_x。
@param Port =LL_GPIO_AF_EXTI_PORTn
@param Line =LL_GPIO_AF_EXTI_LINEx
※每次只能配置一个引脚 Pnx; Pnx 将连接EXTI_LINE_x
*/
__STATIC_INLINE uint32_t LL_GPIO_AF_GetEXTISource(uint32_t Line);/*
  返回连接在EXTI_LINEx上的引脚信息(端口号)。
  @param Line =LL_GPIO_AF_GPIO_LINEx
  @retval:
  LL_GPIO_AF_GPIO_PORTn
*/

EXTI_LINE配置结构体LL_EXTI_InitTypeDef

typedef struct
{
  uint32_t Line_0_31;/*
  EXTI_LINE选择; Line_0_31= LL_EXTI_LINE_x
  */        
  FunctionalState LineCommand; /*
 使能位。LineCommand= ENABLE
  */
  uint8_t Mode;/*
 模式选择; Mode= LL_EXTI_MODE_IT           中断模式
               LL_EXTI_MODE_EVENT        事件模式
               LL_EXTI_MODE_IT_EVENT     中断&事件模式 
  */
  uint8_t Trigger;/*
  触发模式选择; Trigger = LL_EXTI_TRIGGER_NONE           无触发
                        LL_EXTI_TRIGGER_RISING         上升沿触发
                        LL_EXTI_TRIGGER_FALLING        下降沿触发
                        LL_EXTI_TRIGGER_RISING_FALLING 上升/下降均触发
  */
} LL_EXTI_InitTypeDef;

初始化函数LL_EXTI_Init()

ErrorStatus LL_EXTI_Init(LL_EXTI_InitTypeDef *EXTI_InitStruct)/*
  初始化并启用中断EXTI_LINEx。操作成功返回SUCCESS
*/

重设中断结构体

void LL_EXTI_StructInit(LL_EXTI_InitTypeDef *EXTI_InitStruct)
{
  EXTI_InitStruct- >Line_0_31      = LL_EXTI_LINE_NONE;
  EXTI_InitStruct- >LineCommand    = DISABLE;
  EXTI_InitStruct- >Mode           = LL_EXTI_MODE_IT;
  EXTI_InitStruct- >Trigger        = LL_EXTI_TRIGGER_FALLING;
}

软件中断触发函数(模拟外部触发)

__STATIC_INLINE void LL_EXTI_GenerateSWI_0_31(uint32_t ExtiLine)
{//ExtiLine = LL_EXTI_LINE_x;触发Line_x对应的中断处理函数;效果与外部触发相同
  SET_BIT(EXTI- >SWIER, ExtiLine);
}//软件触发寄存器SWIER改变可以通过清零挂起位PR清除

中断线判断函数:

__STATIC_INLINE uint32_t LL_EXTI_IsActiveFlag_0_31(uint32_t ExtiLine);/*
@param ExtiLine =LL_EXTI_LINE_x
当ExtiLine是引发中断函数的中断线时,返回值为!RESET ;反之返回值RESET (=0)*/

挂起位清除函数:

清除函数挂起位,使能下一次中断唤起

__STATIC_INLINE void LL_EXTI_ClearFlag_0_31(uint32_t ExtiLine);/*
@param ExtiLine =LL_EXTI_LINE_x
清除中断挂起位;若中断是由软件模拟外部触发实现的,清除时一并将SWIER位清除
*/

使用案例

void EXTI15_10_IRQHandler(void)
{

 LL_mDelay(10);//按键消抖,防止多次触发(一置位PR即可能再次触发)
 if (LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_13) != RESET)//当中断由EXTI_LINE_13引起
 {
  /* USER CODE BEGIN LL_EXTI_LINE_13 */
    LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_13); //清除标志位
    
    LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_15); //翻转LED
    /* USER CODE END LL_EXTI_LINE_13 */
 }
 if (LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_15) != RESET)//当中断由EXTI_LINE_15引起
 {
  LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_15);  //清除标志位
 }
}
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分