???? 个人主页:???? 长夜漫漫想学习 ????
???? 本文收录专栏:???? ARM学习之路 ????
???? 其他专栏:???? C语言学习之路 ????
???? 学习格言:路漫漫其修远兮,吾将上下而求索
???? 欢迎点赞、关注、收藏( •̀ ω •́ )✧ 一起努力,一起学习!
目录
1、中断概述
1.1、什么是中断?
中断可以理解为当系统出现了意外情况,可以自动停止当前正在执行的程序,并转入执行新情况的程序中进行执行,处理完后会回到原被暂停的程序继续执行。
1.2、中断作用
中断可以解决轮询时不能执行其他程序问题,在一直轮询过程中,需要执行其他情况时,此时就可以使用中断。
1.3、中断控制模块
中断控制模块:GPIO外部中断寄存器(中断触发条件)、GIC中断控制器 (中断管理)、处理器(响应中断)、IRQ中断和FIQ中断(两种中断方式)。
中断可以分为:外部中断和内部中断。
外部中断:中断信号来自于芯片外部,通过引脚与芯片连接,外部模块的中断信号通过引脚(GPIO)提供给中断控制器。
内部中断:中断信号来自于芯片内部的各个硬件模块(控制器),如串口,看门狗,ADC等。
2、中断源配置
GPX1CON[1](中断配置)
GPX1CON[1] :使能管脚为外部中断输入模式
EXT_INT41_MASK(外部中断使能)
0x0:对应中断使能
0x1:屏蔽触发
EXT_INT41_MASK[1](外部中断触发配置)
使能对应中断设置为 0
EXT_INT41_PEND(中断状态寄存器)
GPX1_1引脚接收到中断信号,中断产生,硬件会自动设置为 1。
注意:当中断处理完成后,需要把状态清空
3、GIC(中断控制模块)
分发管脚使能(端口管脚使能):使能相应的中断到分发器,GIC能够接收对应中断,把中断打开。
GIC支持的三种中断
SGI:软件触发中断
PPI:每个CPU核私有的外部中断
SPI:系统的外设中断,GPIO、UART、WDT、ADC等
4、中断信号设置
端口号:25
中断源:57
外部中断引脚:EINT[9]
模式:外部中断
- ICDDCR寄存器(中断总开关)
- 该寄存器允许将挂起的中断转发到CPU接口。
- ICDDCR [0] = 1:开启使能
- ICDISER寄存器(外部中断通道开关)
- 0:禁用对应通道中断
- 1:开启对应通道中断
ICDIPR寄存器:
配置57中断号(GPX1_1):57/4 = 14----1 寄存器编号 = id / 4 位:8 * 余数 ICDIPR14 [15:8] = 优先级 0-255
- ICDIPTR(中断目标CPU寄存器)
- ICDIPTR14-----56\57\58\59四个中断号
- ICCICR_CPUn (CPU通道中断使能)
- 0:禁止中断信号
- 1:开启中断信号
ICCPMR_CPU(CPU的优先级过滤)
该寄存器提供中断优先级过滤器。仅优先级高于该寄存器中值的中断 可以用信号通知处理器。
设置CPU的优先级过滤,低于优先级的就丢弃
ICCPMR_CPU0-4:每个CPU的优先级过滤
ICCICR_CPU0 [7:0] = 255;CPU0过滤优先级低于255,所有要发送到CPU0的中断能够到CPU0
- ICDICPR(GIC中断状态寄存器)
- GIC中断状态寄存器:只要GIC接收到对应中断,就会把对应位设置为1
- ICDICPR1 [25] = 1,硬件自动设置
- ICCIAR_CPU(中断响应寄存器)
- 中断响应寄存器:获取中断号
- ICCEOIR(中断结束处理寄存器)
- 中断结束处理寄存器:清除中断状态标志
5、操作步骤
保存现场
处理异常
处理操作(获取中断号ICCIAR寄存器)
中断标志清除
恢复现场
6、完整程序代码
#include "exynos_4412.h"
#include "uart.h"//调用串口初始化库
void do_irq()
{
//获取中断号
//ICCIAR
int id = 0;
id = CPU0.ICCIAR;
printf("中断号为:%d\n",id); //执行中断程序,打印该 id
//清除GPIO标志
EXT_INT41_PEND |= 1<<1;
//清除GIC标志
ICDICPR.ICDICPR1 |= 1<<25;
//中断标志
CPU0.ICCEOIR = CPU0.ICCEOIR & ~(0x3ff) | id;
}
void key_init()
{
//GPIO设置中断
GPX1.CON |= 0xf<<4;//引脚为中断输入
//配置上升沿为中断源
EXT_INT41_CON = EXT_INT41_CON & ~(0x7<<4) | 0x3<<4;
//使能引脚中断
EXT_INT41_MASK &= ~(1<<1);
//GIC设置
ICDDCR = 1;//GIC使能
//端口使能,引脚中断能够进入GIC, 57中断号(25管脚)进行使能
ICDISER.ICDISER1 |= 1<<25;
//ICDIPR设置中断优先级
//当前按键---57号中断,配置57中断号
ICDIPR.ICDIPR14 = ICDIPR.ICDIPR14 & ~(0xff<<8) | 1<<8;
//产生中断,送入对应CPU
ICDIPTR.ICDIPTR14 = ICDIPTR.ICDIPTR14 & ~(0xff<<8) | 0x1<<8;
//cpu中断通道使能,开启GIC到CPU的中断通道
CPU0.ICCICR = 1;
//CPU过滤优先级中断
CPU0.ICCPMR = 255;
}
void delay()//延时函数
{
int i,j;
for(i = 0;i < 1000;i++)
{
for(j = 0;j <1000;j++);
}
}
int main()
{
uart_init();//串口初始化
key_init();//按下k2按键,执行中断
while(1)//正常执行
{
printf("------程序执行中------\n");
delay();
}
return 0;
}
当按下k2按下按键释放后(上升沿触发),就会暂停当前执行程序,去执行中断任务程序,打印id内容。
✨本篇到此结束啦!欢迎点赞????收藏❤关注????