文章目录
一.概要
中断是指单片机正在处理某个事件A,发生了另一件事件B,请求单片机迅速去处理(中断发生),单片机暂时停止当前的工作(中断响应),转去处理事件B(中断服务),待单片机处理事件B完成后,再回到原来的事件A(断点)继续执行,这一过程称之为中断。
GD32单片机的中断系统支持多种中断类型,包括内部中断和外部中断。内部中断通常由处理器内部的事件引发,如定时器溢出、除零错误等,而外部中断则由外部硬件或设备触发的事件引发,如按键按下、传感器触发等。
二.可嵌套的向量中断控制器 (NVIC)
Cortex®-M4 集成了嵌套式矢量型中断控制器(Nested Vectored Interrupt Controller (NVIC))来实现高效的异常和中断处理,NVIC 实现了低延迟的异常和中断处理,以及电源管理控制。
NVIC的核心功能是中断优先级分组、中断优先级的配置、读中断请求标志、清除中断请求标志、使能中断、清除中断等,它控制着91个可屏蔽的外设中断,NVIC在处理(Handler)模式下对所有异常进行优先级区分以及处理,可提供16个中断优先等级。当异常发生时,系统自动将当前处理器工作状态压栈,在执行完中断服务子程序(ISR)后自动将其出栈。外部中断信号从核外发出,信号最终要传递到NVIC(嵌套向量中断控制器)。NVIC跟内核紧密耦合,它控制着整个芯片中断的相关功能。
三.中断向量表
在中断向量表里列出了各种外部中断。
下图是内核的中断:
下图是外设相关的91个可屏蔽中断:
四.中断优先级详解
NVIC支持优先级分组,中断优先级分为组优先级(Pre-priority)与组内的子优先级(Sub-priority)。只有组优先级才决定了对中断异常的抢占权,当处理器正在执行一个中断异常处理程序时,另一个与被处理的中断具有相同组优先级的中断不会优先于该处理程序。如果多个中断具有相同的组优先级,则子优先级将确定处理它们的顺序。如果多个挂起中断具有相同的组优先级和子优先级,则首先处理IRQ号最低的中断。
优先级数值越小表示优先级高。
五.GD32F4外部中断控制器(EXTI)
1.EXTI简介
GD32单片机的外部中断/事件控制器(External Interrupt/Event Controller,简称EXTI),使得微控制器能够高效地响应外部事件并执行相应的任务,EXTI允许GD32微控制器对外部事件进行监测和响应,这些事件可以是来自GPIO引脚的电平变化信号。当外部事件发生时,EXTI能够立即唤醒微控制器,并执行预定义的中断服务程序(ISR)或者事件处理函数,我们接下去对EXTI外部中断进行详细介绍。
EXTI(中断/事件控制器)包括20个相互独立的边沿检测电路并且能够向处理器内核产生中断请求或唤醒事件。EXTI有三种触发类型:上升沿触发、下降沿触发和任意沿触发。EXTI中的每一个边沿检测电路都可以独立配置和屏蔽。
2.EXTI在中断向量表的位置
GPIO口外部中断在中断向量表中分配了16个中断向量(EXTI0~EXTI15)
GPIO对应的外部中断,例如PA0,PB0,PC0对应的中断服务程序都是EXTI0_IRQHandler,一般只能选择其中一个引脚作为EXTI0中断输入脚。
3.EXTI外部中断产生的信号流向
如下图是外部中断的信号流向
1.外部中断可以是GPIO的任意一个引脚,就是高低电平信号输入脚。
2.外部信号经过一个边沿检测电路,通过极性控制器选择边沿,检测到了就在后面的或门处给个1,中断屏蔽寄存器设置为1表示开放中断,电路输出的信号会被保存到挂起寄存器(EXTI_PD)内,出来的信号发送到内核NVIC中请求产生中断,并跳转到对应的中断服务函数。
4.EXTI中断产生后的中断服务程序
中断向量表中的中断服务函数就在下图中启动文件的中,中断产生后就会跳入相应中断服务程序,我们应用程序就可以对中断后需要做的事进行修改,比如PA0产生的EXTI0中断,中断服务程序就是EXTI0_IRQHandler。
如下面代码所示,一般在gd32f4xx_it.c中对中断服务函数进行修改就可以。
void EXTI0_IRQHandler(void)
{
exti_interrupt_flag_clear(EXTI_0);//清除外部中断0标志
IntFlag^=0x01;
if(IntFlag)
{
gpio_bit_set(GPIOB, GPIO_PIN_4);
}else{
gpio_bit_reset(GPIOB, GPIO_PIN_4);
}
}
六.GPIO输入中断的例程实验
硬件准备:
STLINK接GD32F407VET6开发板,STLINK接电脑USB口。
实验原理:
查看板子原理图,如下图所示,可以了解到按键连接到单片机的PA0引脚,LED灯连接到单片机的PB4引脚。所以通过板子的 PA0 引脚配置成中断输入引脚,PB4 引脚配置成输出,按下按键,PA0 引脚就会进入一次外部中断,检测到外部中断,改变 PB4 输出电平的高低,从而实现 LED 灯的亮灭。
主要代码:
#include "gd32f4xx.h"
#include "gd32f4xx_libopt.h"
#include "systick.h"
int main(void)
{
systick_config();//配置系统主频168M,外部8M晶振,配置在#define __SYSTEM_CLOCK_168M_PLL_8M_HXTAL (uint32_t)(168000000)
rcu_periph_clock_enable(RCU_GPIOB);//使能GPIOB时钟
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_4);//PB4配置成输出
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);//PB4配置成推挽输出,50M速度
//配置PA0外部中断
rcu_periph_clock_enable(RCU_GPIOA);
gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN_0);//PA0配置成下拉输入
/* enable and set key EXTI interrupt to the lowest priority */
nvic_irq_enable(EXTI0_IRQn, 2U, 0U);//中断使能
/* configure key EXTI line */
exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_RISING);//上升沿触发
exti_interrupt_flag_clear(EXTI_0);
while(1)
{
}
}
void EXTI0_IRQHandler(void)
{
exti_interrupt_flag_clear(EXTI_0);//清除外部中断0标志
IntFlag^=0x01;
if(IntFlag)
{
gpio_bit_set(GPIOB, GPIO_PIN_4);
}else{
gpio_bit_reset(GPIOB, GPIO_PIN_4);
}
}
调试代码:
在中断服务程序EXTI0_IRQHandler中设置断点,按下板子上的按键(WK_UP),可以看到程序运行到断点处。如下图所示,并且PD0标志被置位。
查看应用手册,可以看到有中断产生,EXTI_PD寄存器对应位就会置1,如果是EXTI0中断,PD0标志就会被置位。
七.工程源代码下载
源代码链接如下:
CSDN代码
八.小结
中断是GD32单片机开发中经常会用到的功能,对中断有了一定了解,在开发中应用中断,在程序中应用中断能使单片机的运行效率提升很多。