中断概念
中断对于单片机来说是必不可少的存在。例如使用一个按键打开一个灯的方法,就可以使用中断的方式实现,并且效果更好。
中断的概念比较容易理解,就相当于做饭的时候,你的主任务是炒菜,炒菜炒到一半,来了个电话你就需要优先去接电话,然后电话处理完后才会继续回归主任务进行炒菜。这就是一个中断的实际概念。
中断对于 STM32
来说是必不可少的一部分,STM32
支持的中断类型也很多,在这里主要介绍其概念,并且以一个简易的外部按键输入中断作为演示示例。
本文以一个外部按键输入中断更改 LED 灯亮灭为例进行说明,其余中断类型在遇到对应模式时再具体介绍。
中断操作
中断操作的步骤基本为一下步骤:
- 开启时钟线
- 初始化中断向量表
- 初始化 GPIO 口
- 初始化中断模式
- 进行中断响应处理
- 清除中断标志位
我们将按照上面步骤一步步进行处理。
开启时钟线
开始时钟线主要使用 RCC_APB2PeriphClockCmd
和 RCC_APB1PeriphClockCmd
这两个函数。
具体使用哪一个函数查阅下图:
根据所挂载的时钟线选择响应函数。
这里以 RCC_APB2PeriphClockCmd
为例:
其中第一个参数的选择范围如下:
这里以开启 GPIOE
以及 复用 IO
始终为例:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE| RCC_APB2Periph_AFIO,ENABLE);
初始化中断向量表
主要使用 NVIC_PriorityGroupConfig
以及 NVIC_Init
函数NVIC_PriorityGroupConfig
函数主要用于设置优先级组合。具体使用方法如下:
然后是使用 NVIC_Init
函数进行初始化:
此函数与 GPIO 中的 GPIO_Init
函数相似,使用结构体 NVIC_InitTypeDef
作为参数进行初始化。其相对应的参数如下:
-
NVIC_IRQChannel
-
NVIC_IRQChannelPreemptionPriority
和NVIC_IRQChannelSubPriority
其中在相同的PreemptionPriority
下,优先响应SubPriority
优先级高的中断。在不同的PreemptionPriority
下,优先响应PreemptionPriority
优先级高的,SubPriority
没影响。 -
NVIC_IRQChannelCmd
这里以开启PE4
外部中断为例:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitTypeDef NVIC_Param;
NVIC_Param.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_Param.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_Param.NVIC_IRQChannelSubPriority = 1;
NVIC_Param.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_Param);
初始化 GPIO 口
主要使用 GPIO_Init
和 GPIO_EXTILineConfig
函数。其中 GPIO_Init
函数的使用方式详见:GPIOGPIO_EXTILineConfig
函数如下:
这里以开启 PE4
的外部中断为例:
GPIO_InitTypeDef GPIO_Param;
GPIO_Param.GPIO_Pin=GPIO_Pin_4;
GPIO_Param.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Param.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOE,&GPIO_Param);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
初始化中断
主要使用 EXTI_Init
函数进行初始化,看名字就能看出来其与之前的 NVIC_Init
函数使用方法类似。
使用 EXTI_InitTypeDef
函数进行初始化。
-
EXTI_Line
其中选择具体哪一个看如下图片:
-
EXTI_Mode
二者的区别主要是事件请求会等待当前事件完成后再响应,而中断请求会直接打断当前事件直接请求。 -
EXTI_Trigger
-
EXTI_LineCmd
这里以开启PE4下降沿
中断为例:
EXTI_InitTypeDef EXTI_Param;
EXTI_Param.EXTI_Line = EXTI_Line4;
EXTI_Param.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_Param.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Param.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_Param);
中断响应处理
中断响应处理是我们进入中断后进行响应处理的地方,也是最重要的地方。不同的中断会调用不同的中断处理函数。所以我们需要根据我们初始化的中断选用不同的中断处理函数。
中断处理函数主要查看程序配置中的 stm32f10x.h
文件,然后根据自己的启动文件类别进行操作, 我这里使用的是 hd
类型的启动文件,这里值贴出对应的中断处理函数
typedef enum IRQn
{
/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
/****** STM32 specific Interrupt Numbers *********************************************************/
WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */
PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */
TAMPER_IRQn = 2, /*!< Tamper Interrupt */
RTC_IRQn = 3, /*!< RTC global Interrupt */
FLASH_IRQn = 4, /*!< FLASH global Interrupt */
RCC_IRQn = 5, /*!< RCC global Interrupt */
EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */
EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */
EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */
EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */
EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */
DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */
DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */
DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */
DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */
DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */
DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */
DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */
ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */
USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */
CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */
TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */
TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */
TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
USART1_IRQn = 37, /*!< USART1 global Interrupt */
USART2_IRQn = 38, /*!< USART2 global Interrupt */
USART3_IRQn = 39, /*!< USART3 global Interrupt */
EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
TIM8_BRK_IRQn = 43, /*!< TIM8 Break Interrupt */
TIM8_UP_IRQn = 44, /*!< TIM8 Update Interrupt */
TIM8_TRG_COM_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt */
TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */
ADC3_IRQn = 47, /*!< ADC3 global Interrupt */
FSMC_IRQn = 48, /*!< FSMC global Interrupt */
SDIO_IRQn = 49, /*!< SDIO global Interrupt */
TIM5_IRQn = 50, /*!< TIM5 global Interrupt */
SPI3_IRQn = 51, /*!< SPI3 global Interrupt */
UART4_IRQn = 52, /*!< UART4 global Interrupt */
UART5_IRQn = 53, /*!< UART5 global Interrupt */
TIM6_IRQn = 54, /*!< TIM6 global Interrupt */
TIM7_IRQn = 55, /*!< TIM7 global Interrupt */
DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */
DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
自行根据此内容进行查询选择即可。查询到对应的中断处理函数后,在自己的文件中实现对应的函数即可。
这里以 PE4
的中断为例:
// 中断响应函数
void EXTI4_IRQHandler()
{
if (EXTI_GetFlagStatus(EXTI_Line4) == SET)
{
GPIO_Toggle(GPIOB,GPIO_Pin_5);
//清除中断标志位
EXTI_ClearITPendingBit(EXTI_Line4);
}
}
其中的 EXTI_GetFlagStatus
函数用于防抖,用法如下:
此函数与 EXTI_GetITStatus
函数作用相同,看个人爱好。
文章来源:https://www.toymoban.com/news/detail-795159.html
清除中断标志位
清除中断标志位十分重要!不进行清除程序将一直处于中断中。
主要使用的函数是 EXTI_ClearITPendingBit
其用法如下:
示例代码如下:文章来源地址https://www.toymoban.com/news/detail-795159.html
EXTI_ClearITPendingBit(EXTI_Line4);
到了这里,关于STM32 外部中断 标准库函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!