【ARM】中断控制 ——第六篇

时间:2022-10-10 10:03:35

【ARM】中断控制 ——第六篇

???? 个人主页:???? 长夜漫漫想学习 ????

???? 本文收录专栏:???? ARM学习之路 ????

???? 其他专栏:???? C语言学习之路 ????

???? 学习格言:路漫漫其修远兮,吾将上下而求索

???? 欢迎点赞、关注、收藏( •̀ ω •́ )   一起努力,一起学习!

目录

1、中断概述

1.1、什么是中断?

1.2、中断作用

1.3、中断控制模块

2、中断源配置

3、GIC(中断控制模块)

4、中断信号设置

5、操作步骤

6、完整程序代码


1、中断概述

1.1、什么是中断?

        中断可以理解为当系统出现了意外情况,可以自动停止当前正在执行的程序,并转入执行新情况的程序中进行执行,处理完后会回到原被暂停的程序继续执行。

1.2、中断作用

        中断可以解决轮询时不能执行其他程序问题,在一直轮询过程中,需要执行其他情况时,此时就可以使用中断。

1.3、中断控制模块

        中断控制模块:GPIO外部中断寄存器(中断触发条件)、GIC中断控制器 (中断管理)、处理器(响应中断)、IRQ中断和FIQ中断(两种中断方式)。

【ARM】中断控制 ——第六篇

        中断可以分为:外部中断和内部中断。

        外部中断:中断信号来自于芯片外部,通过引脚与芯片连接,外部模块的中断信号通过引脚(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、操作步骤

  1. 保存现场

  2. 处理异常

    处理操作(获取中断号ICCIAR寄存器)

    中断标志清除

  3. 恢复现场

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内容。

 ✨本篇到此结束啦!欢迎点赞????收藏❤关注????

【ARM】中断控制 ——第六篇