中断的定义:是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。
事件的定义:是可以被控件识别的操作,如按下确定按钮,选择某个单选按钮或者复选框。
中断事件的定义:是可以导致中断发生的事件。
NVIC是内核的外设:
配置中断的时候NVIC的配置为:
- 优先级分组:5个分组(0-4),0-4分别代表抢占优先级所占位数
- 抢占优先级:1分组的话位0-1(占一位)
- 子优先级:1分组的话为0-7(占三位)
- 使能中断通道:使能中断/失能中断
- 配置中断源:中断源不能写错,在stm32f10x.h的IRQn有具体定义
EXIT是片上外设:
配置中断EXIT的步骤是:
- 中断/事件线选择
- 模式选择(是产生中断还是事件)
- 触发类型(上升沿/下降沿)
- EXIT使能
EXIT是外部中断/事件控制器,管理20条中断/事件线,每个事件线对应一个边沿检测器,可以实现输入信号的上升沿和下降沿检测:
原理图如下:
标准库位每个外设都提供了一个初始化结构体,在stm32f10x_外设.h文件中,结构体里的成员用于设置外设工作参数,并由初始化函数(在stm32f10x_外设.c文件)来调用,这些设定的参数将会配置到对应的寄存器里,以达到配置外设工作环境的目的。
bsp_exti.h文件如下:
#ifndef __EXTI_ #define __EXTI_ #include "stm32f10x.h" #define KEY1_INT_GPIO_PORT GPIOA #define KEY1_INT_GPIO_PIN GPIO_Pin_0 #define KEY1_INT_GPIO_CLK (RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO) #define KEY1_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOA #define KEY1_INT_EXTI_PINSOURCE GPIO_PinSource0 #define KEY1_INT_EXTI_LINE EXTI_Line0 #define KEY1_INT_EXTI_IRQ EXTI0_IRQn #define KEY1_IRQHandler EXTI0_IRQHandler #define KEY2_INT_GPIO_PORT GPIOC #define KEY2_INT_GPIO_PIN GPIO_Pin_13 #define KEY2_INT_GPIO_CLK (RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO) #define KEY2_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOC #define KEY2_INT_EXTI_PINSOURCE GPIO_PinSource13 #define KEY2_INT_EXTI_LINE EXTI_Line13 #define KEY2_INT_EXTI_IRQ EXTI15_10_IRQn #define KEY2_IRQHandler EXTI15_10_IRQHandler void EXTI_Key_Config(void); #endif
bsp_exti.c文件如下:
#include "bsp_exti.h" static void NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ; NVIC_Init(&NVIC_InitStructure); } void EXTI_Key_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK|KEY2_INT_GPIO_CLK,ENABLE); NVIC_Config();//先配置内核的NVIC GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;//配置输入信号的引脚及模式 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);//初始化输入信号的配置 GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE);//信号源选择 EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;//中断线选择 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断模式 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//触发类型 EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能中断 EXTI_Init(&EXTI_InitStructure);//初始化中断配置 GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure); GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, KEY2_INT_EXTI_PINSOURCE); EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); }
main.c文件如下:
#include"stm32f10x.h" #include"bsp_led.h" #include"bsp_exti.h" int main(void) { LED_GPIO_Config(); EXTI_Key_Config(); while(1) { } }
中断处理函数
void KEY1_IRQHandler(void) { //确保是否产生了EXTI Line中断 if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) { // LED1 取反 red_TOGGLE; //清除中断标志位 EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE); } } void KEY2_IRQHandler(void) { //确保是否产生了EXTI Line中断 if(EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) { // LED2 取反 green_TOGGLE; //清除中断标志位 EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE); } }