对于SMT32中断响应分为两种:抢占优先级,响应优先级。
详细可参考:【STM32开发】STM32外部中断
注意:A > B是指中断级别更高,0是最高,15为最小,0 > 15
举个栗子:
有A、B两个中断
1.B先进入中断子程序,但并没有执行完,此时A中断触发,这时候B停止,让A先执行。
2.A先进入中断子程序,但并没有执行完,此时B中断触发,这时候B必须等待A执行完才能执行。
3.A、B中断同时触发,此时A先进入中断子程序,B必须等待完A执行完才能执行。
1.B先进入中断子程序,但并没有执行完,此时A中断触发,这时候A必须等待B执行完。
2.A先进入中断子程序,但并没有执行完,此时B中断触发,这时候B必须等待A执行完。
3.A、B中断同时触发,此时A优先进入中断子程序,B必须等待完A执行完才能执行。
硬件序号唯一,比较硬件中断编号
测试板子为:正点原子战舰V3 STM32F103ZET6,野火的103修改对应的管脚即可。
抢占式优先级实验:
使用按键1点亮LED0,使用按键2点亮LED1
中断优先级:按键1 > 按键2
1.按键1按下,LED0亮,之后程序while(1)死循环模拟按键1忙碌,按下按键2查看LED1亮灭情况。
2.按键2按下,LED1亮,之后程序while(1)死循环模拟按键2忙碌,按下按键1查看LED0亮灭情况。
实验结果:
1.按键1按下,LED0亮;按键2按下后LED1不亮。
2.按键2按下,LED1亮;按键1按下后LED0亮。
以下为测试代码:
key.c
#include "stm32f10x.h"
#include "key.h"
#include "led.h"
int key_exit_init(void);
int key_init()
{
/*按键初始化*/
GPIO_InitTypeDef key_structure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
key_structure.GPIO_Pin = KEY1_PIN;
key_structure.GPIO_Speed = GPIO_Speed_10MHz;
key_structure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(KEY1_PORT, &key_structure);
key_exit_init();
return 0;
}
int key_exit_init()
{
/*按键1外部中断初始化*/
NVIC_InitTypeDef key_nvic_structure;
EXTI_InitTypeDef key_exti_structure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
key_nvic_structure.NVIC_IRQChannel = KEY1_CHANNEL;
key_nvic_structure.NVIC_IRQChannelPreemptionPriority = 1;
key_nvic_structure.NVIC_IRQChannelSubPriority = 1;
key_nvic_structure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&key_nvic_structure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(KEY1_PORTSOURCE, KEY1_PINSOURCE);
key_exti_structure.EXTI_Line = KEY1_LINES;
key_exti_structure.EXTI_Mode = EXTI_Mode_Interrupt;
key_exti_structure.EXTI_Trigger = EXTI_Trigger_Rising;
key_exti_structure.EXTI_LineCmd = ENABLE;
EXTI_Init(&key_exti_structure);
/*按键2外部中断初始化*/
NVIC_InitTypeDef key_nvic_structure2;
EXTI_InitTypeDef key_exti_structure2;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
key_nvic_structure2.NVIC_IRQChannel = KEY2_CHANNEL;
key_nvic_structure2.NVIC_IRQChannelPreemptionPriority = 2;
key_nvic_structure2.NVIC_IRQChannelSubPriority = 2;
key_nvic_structure2.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&key_nvic_structure2);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(KEY2_PORTSOURCE, KEY2_PINSOURCE);
key_exti_structure2.EXTI_Line = KEY2_LINES;
key_exti_structure2.EXTI_Mode = EXTI_Mode_Interrupt;
key_exti_structure2.EXTI_Trigger = EXTI_Trigger_Rising;
key_exti_structure2.EXTI_LineCmd = ENABLE;
EXTI_Init(&key_exti_structure2);
return 1;
}
void EXTI2_IRQHandler()
{
EXTI_ClearFlag(KEY2_LINES);
while(1)
{
LED1_ON;//按下按键后点亮并死循环模拟忙碌
}
}
void EXTI3_IRQHandler()
{
EXTI_ClearFlag(KEY1_LINES);
while(1)
{
LED0_ON;//按下按键后点亮并死循环模拟忙碌
}
}
#ifndef _KEY_H_
#define _KEY_H_
#define KEY1_PORT GPIOE
#define KEY1_PIN GPIO_Pin_3
#define KEY1_CHANNEL EXTI3_IRQn
#define KEY1_LINES EXTI_Line3
#define KEY1_PORTSOURCE GPIO_PortSourceGPIOE
#define KEY1_PINSOURCE GPIO_PinSource3
#define KEY1_VALUE GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3)
#define KEY2_PORT GPIOE
#define KEY2_PIN GPIO_Pin_2
#define KEY2_CHANNEL EXTI2_IRQn
#define KEY2_LINES EXTI_Line2
#define KEY2_PORTSOURCE GPIO_PortSourceGPIOE
#define KEY2_PINSOURCE GPIO_PinSource2
#define KEY_VALUE GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2)
#define KEY_DOWN 0
#define KEY_UP 1
int key_init(void);
#endif
#include "stm32f10x.h"
#include "led.h"
int LED_init()
{
GPIO_InitTypeDef LED_structure;
RCC_APB2PeriphClockCmd(LED1_CLK | LED0_CLK, ENABLE);
LED_structure.GPIO_Mode = GPIO_Mode_Out_PP;
LED_structure.GPIO_Pin = LED1_PIN;
LED_structure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED1_PORT, &LED_structure);
LED1_OFF;
LED_structure.GPIO_Pin = LED0_PIN;
GPIO_Init(LED0_PORT, &LED_structure);
LED0_OFF;
return 0;
}
#ifndef _LED_H_
#define _LED_H_
#define LED0_PORT GPIOB
#define LED0_PIN GPIO_Pin_5
#define LED0_CLK RCC_APB2Periph_GPIOB
#define LED0_ON GPIO_ResetBits(LED0_PORT, LED0_PIN)
#define LED0_OFF GPIO_SetBits(LED0_PORT, LED0_PIN)
#define LED0_TROGGLE (LED0_PORT->ODR ^= LED0_PIN)
#define LED1_PORT GPIOE
#define LED1_PIN GPIO_Pin_5
#define LED1_CLK RCC_APB2Periph_GPIOE
#define LED1_ON GPIO_ResetBits(LED1_PORT, LED1_PIN)
#define LED1_OFF GPIO_SetBits(LED1_PORT, LED1_PIN)
#define LED1_TROGGLE ((LED1_PORT->ODR) ^= LED1_PIN)
int LED_init(void);
#endif
系统定时器与外部中断:STM32 系统定时器与外部中断响应级别实验测试