arm7 LPC2103 中断的处理方法

发布者:电子设计探索者最新更新时间:2019-05-07 来源: eefocus关键字:arm7  LPC2103  中断 手机看文章 扫描二维码
随时随地手机看文章

        向量中断控制器(VIC)具 有 32 个中断请求输入,可将其编程分为3 类:FIQ 、向量IRQ和非向量IRQ 。可编程分配机制意味着不同外设的中断优先级可以动态分配并调整。

快速中断请求(FIQ )要求具有最高优先级。如果分配给 FIQ 的请求多于1 个,VIC 将中断请求“相或”后向ARM处理器产生 FIQ 信号。当只有一个中断被分配为 FIQ 时可实现

最短的FIQ 等待时间,因为FIQ 服务程序只要简单地启动器件的处理就可以了。但如果分配给FIQ 级的中断多于1 个,FIQ 服务程序从 VIC 中读出一个字来识别产生中断请求的 FIQ中断源是哪一个。

        向量IRQ 具有中等优先级。该级别可分配32 个请求中的 16 个。32个请求中的任意一个都可分配到16 个向量IRQ slot 中的任意一个,其中 slot0 具有最高优先级,而 slot15 则为最低优先级。


        非向量IRQ 的优先级最低。VIC 将所有向量和非向量IRQ “相或”向 ARM处理器产生IRQ 信号。IRQ 服务程序可通过读取VIC 的一个寄存器立即启动并跳转到相应地址。如果有任意一个向量IRQ 发出请求,VIC 则提供最高优先级请求IRQ 服务程序的地址,否则提供所默认程序的地址。该默认程序由所有非向量IRQ 共用。默认程序可读取另一个VIC 寄存器以确定哪个IRQ 被激活。




一、向量中断


1.1 第一种方法,每次中断都可以直接跳转到对应的中断处理函数


1.1.1 启动代码

        ARM

__vector:

        ;;

        ldr   pc,[pc,#+24]              ;; Reset

        ldr   pc,[pc,#+24]              ;; Undefined instructions

        B   .                           ;; Software interrupt (SWI/SVC)

        ldr   pc,[pc,#+24]              ;; Prefetch abort

        ldr   pc,[pc,#+24]              ;; Data abort

__vector_0x14:

        DC32  0                         ;; RESERVED

        ldr   pc,[pc,#-0xFF0]           ;; IRQ

        ldr   pc,[pc,#+24]              ;; FIQ


        DC32  __iar_program_start       ;; Reset

        DC32  undef_handler             ;; Undefined instructions

        DC32  0                         ;; Software interrupt (SWI/SVC)

        DC32  prefetch_handler          ;; Prefetch abort

        DC32  data_handler              ;; Data abort

        DC32  0                         ;; RESERVED

        DC32  0                         ;; IRQ

        DC32  fiq_handler               ;; FIQ

    这里FIQ很好理解,但这里的IRQ为什么要PC-0XFF0呢?


     结合ARM7的三级流水线,这个问题应该就很简单了,当程序跳到0X18执行指令的时候,PC应该是0x18+8=0x20,

     然后0x20-0xff0=0xfffff030,此处0XFFFFF030正好是 VICVectAddr 的地址,意思就是通过一条简单的ARM指令,

     实现了IRQ的程序跳转


1.1.2 初始化,以串口中断为例

设置 0号 IRQ slot (向量中断中优先级最高)为串口中断,并且把 中断处理函数 IRQ_UART_0 赋给 VICVectAddr0

void Init_uart0()

{

    U0LCR = 0x83; //使能访问除数寄存器,8位字符长度     

    U0DLM = 0x00; //115200时为6   9600时为0x006c

    U0DLL = 0x6c; 

    U0LCR = 0x03; //禁止访问除数寄存器       

    U0IER = 0x03; //允许接收数据可用中断[第0位]和发送缓冲为空中断[第1位] 

    //以下是中断设置 设置为中断通道0

    VICIntSelect = 0x00000000;

    VICVectCntl0 = 0x26; //第5位置1:向量使能,[4:0]中断源序号

    VICVectAddr0 = (unsigned long)&IRQ_UART_0;

    //jtk 当发生向量中断时处理器自动把 VICVectAddrN 赋给 VICVectAddr

    VICIntEnable = 0x00000040;   

    PINSEL0 |= 0x00000005;

}


1.1.3 中断处理函数

__irq __arm void IRQ_UART_0(void)

{

    …………

    VICVectAddr = 0x00;

}




1.2 第二方法,先跳转到一个处理函数然后再跳转到对应的中断处理函数


1.2.1 启动代码


        ARM

__vector:  

        ;jtk 绝对跳转,跳转到相应的异常处理程序,PC总是指向当前指令的下两条指令的地址,即PC的值为当前指令的地址值加8个字节

        ;jtk 所以LDR PC, [PC,#24]跳转到24+8=32字节后

        ldr   pc,[pc,#+24]              ;; Reset jtk 跳转到__iar_program_start

        ldr   pc,[pc,#+24]              ;; Undefined instructions

        B   .                           ;; Software interrupt (SWI/SVC)

        ldr   pc,[pc,#+24]              ;; Prefetch abort

        ldr   pc,[pc,#+24]              ;; Data abort

__vector_0x14

        DC32  0                         ;; RESERVED

        ldr   pc,[pc,#+24]              ;; IRQ

        ldr   pc,[pc,#+24]              ;; FIQ

;jtk 上面的中断向量跳转到这里来,如果在c语言中有定义,

;下面的标号如果在c语言中有相应的处理程序,那么一旦有中断产生就会跳到相应的中断函数去

        DC32  __iar_program_start       ;; Reset

        DC32  undef_handler             ;; Undefined instructions

        DC32  0                         ;; Software interrupt (SWI/SVC)

        DC32  prefetch_handler          ;; Prefetch abort

        DC32  data_handler              ;; Data abort

        DC32  0                         ;; RESERVED

        DC32  irq_handler               ;; IRQ  跳转到 irq_handler 这个函数

        DC32  fiq_handler               ;; FIQ


        

void Init_key()

{

    PINSEL1_bit.P0_16 = 1;//引脚P0.16选择为外部中断功能


    EXTWAKE=0X00;//jtk 不作为唤醒用,为1时处理器从掉电模式唤醒

    EXTMODE =0x00;//jtk 为0用电平激活,为1时是边缘激活

    EXTPOLAR=0x00;//jtk 为低电平或下降沿有效


    VICIntSelect_bit.EINT0 =0;  //jtk 中断选择寄存器第14位是0就行。

    //第5位置1:向量使能,[4:0]中断源序号

    VICVectCntl9 = 0x20|14;//将9号IRQ slot设置为向量中断(第5位为1使能向量中断,为0时是非向量中断)

    VICVectAddr9 = (unsigned int)KEY_IRQ; //当设置为向量中断时,中断函数地址给 VICVectAddrN  

    VICDefVectAddr = (unsigned long)KEY_IRQ; //当设置为非向量中断时,中断函数地址给 VICDefVectAddr 

    //当一个IRQ服务程序读取向量地址寄存器 VICVectAddr ,并且没有 IRQ slot 响应时,则返回 VICDefVectAddr 的地址

    //所以当没有 IRQ slot 响应时,则 VICDefVectAddr 的地址被读取了,这样就变成了处理非向量中断的程序了

    //KEY_IRQ; //中断函数地址 


    EXTINT=0X01;//jtk 通过向 EXTINT 寄存器 写入 1 来将其清零

    VICIntEnable_bit.EINT0 = 1;//中断使能寄存器 查表可知ext0的中断源号是14,第14位置1.

}


 __irq __arm void irq_handler (void)        //公共中断处理函数,检查 VICVectAddr 是否为空

{

    void (*interrupt_function)();

    unsigned int vector;


    vector = VICVectAddr;     // Get interrupt vector.

//jtk 如果作为向量中断,这里把 VICVectAddrN 赋给 vector 和把 VICVectAddr 赋给 vector 都可以,

//jtk 当发生向量中断时处理器自动把 VICVectAddrN 赋给 VICVectAddr

    interrupt_function = (void(*)())vector;

    if(interrupt_function !=NULL){

       interrupt_function();  // Call vectored interrupt function.

    }else{

        VICVectAddr = 0;      // Clear interrupt in VIC.

    }

}




二、非向量中断


        ARM

__vector:  

        ;jtk 绝对跳转,跳转到相应的异常处理程序,PC总是指向当前指令的下两条指令的地址,即PC的值为当前指令的地址值加8个字节

        ;jtk 所以LDR PC, [PC,#24]跳转到24+8=32字节后

        ldr   pc,[pc,#+24]              ;; Reset jtk 跳转到__iar_program_start

        ldr   pc,[pc,#+24]              ;; Undefined instructions

        B   .                           ;; Software interrupt (SWI/SVC)

        ldr   pc,[pc,#+24]              ;; Prefetch abort

        ldr   pc,[pc,#+24]              ;; Data abort

__vector_0x14

        DC32  0                         ;; RESERVED

        ldr   pc,[pc,#+24]              ;; IRQ

        ldr   pc,[pc,#+24]              ;; FIQ

;jtk 上面的中断向量跳转到这里来,如果在c语言中有定义,

;下面的标号如果在c语言中有相应的处理程序,那么一旦有中断产生就会跳到相应的中断函数去

        DC32  __iar_program_start       ;; Reset

        DC32  undef_handler             ;; Undefined instructions

        DC32  0                         ;; Software interrupt (SWI/SVC)

        DC32  prefetch_handler          ;; Prefetch abort

        DC32  data_handler              ;; Data abort

        DC32  0                         ;; RESERVED

        DC32  irq_handler               ;; IRQ  跳转到 irq_handler 这个函数

[1] [2]
关键字:arm7  LPC2103  中断 引用地址:arm7 LPC2103 中断的处理方法

上一篇:LPC17XX 学习之系统时钟与功率控制
下一篇:KEIL / MDK生成BIN文件

推荐阅读最新更新时间:2024-11-04 11:27

基于ARM7中断程序的设计
1 存储器部分原理 笔者在设计一项目时采用LPC2458。此CPU为ARM7内核,带512K字节的片内FLASH,98k字节的片内RAM,支持片外LOCAL BUS总线,可从片外NOR FLASH启动CPU。由于代码量较大,程序放在片外的NOR FLASH中。且存在片外NOR FLASH在运行程序时,需对片外的NOR FLASH擦写的需求。图1为存储部分框图。 图1 存储部分原理框图 在设计中,片外NOR FLASH的大小为16M字节。其中2M规划为存放运行程序,剩余的空间用于产品运行日志,告警灯存储空间。因此存在着在程序运行时对片外NOR FLASH擦写的需求。如果程序正在正常运行的片外FLASH中去擦写
[单片机]
基于<font color='red'>ARM7</font>软<font color='red'>中断</font>程序的设计
1.5.6_定时器中断程序示例
通过S3C2440内部的定时器,可以产生稳定的定时器中断,示例程序为每0.5s产生一次中断,在中断中循环点亮小灯。 首先,S3C2440内部的定时器运行示意图如下: 每来一个时钟脉冲,TCNTn的计数值就会减1。从定时器操作示意图可以看出,只在TCNTn降到0时,才发生中断,在TCNTn = TCMPn时,可以发生输出引脚输出变化,这可以用来输出不同占空比的PWM波。 定时器的时钟源是PCLK,PCLK经过8位的预分频和多路选择器,将时钟供给定时器。 设置Timer主要就步骤: 设置时钟; 设置初值; 加载初值,启动timer; 设置为自动加载; 设置中断相关。 具体的寄存器操作,查看S3C2440第十章的寄存
[单片机]
1.5.6_定时器<font color='red'>中断</font>程序示例
利用单片机定时中断实现软定时器
以下是代码实现已经测试并用到项目上课放心使用 Author : 吾本杞人 #include reg52.h #include Intrins.h #include TypeDef.h #include CPUPin_Def.h #include VarDef.h #define TIME_BASE_2MS 2 #define TIME_BASE_500MS 250 #define TIME_BASE_10MS 5 #define F_OSC 110592 //定义这个是默认按照11.0592MHZ的晶振算的 TH0 TL0的值 方式1 16位定时器 //注意这种写法只
[单片机]
MSP430中断的一个细节问题
关于中断标志: 从SPI发送一字节数据: void SPI_Set_SD_Byte(unsigned char txData) { UCB0TXBUF = txData; // 写入发送缓冲区 while ((UCB0IFG & UCTXIFG) == 0); // 等待发送完毕 } 分析:以9600bps 发送一字节 1ms估算,而以12MHz时钟执行(UCB0TXBUF = txData;)需要时间大概1us, 因此可怕的事情发生了,要等待发送完毕需要浪费3999个CPU周期去查询。如果等待过程换成休眠多好啊! 看下面程序: void SPI_Set_SD_Byte(unsign
[单片机]
arm7 力天电子lpc2148 GPIO之按键输入试验
此实验中摁下某个按键后,把相关的信号并行传递到74HC165上,然后再通过串行方式传到处理器中,处理器在通过控制P0.22口(MAT0.0)来控制蜂鸣器 部分电路图如下所示: 注意:9号引脚接的是2148的MISO0(P0.5) #include NXP/iolpc2148.h //宏定义 #define SCLK 0x01 24 #define SCK0 0x01 4 #define MISO 0x01 5 #define MOSI 0x01 6 #define RCK 0x01 7 void HC595_Init(void); void
[单片机]
<font color='red'>arm7</font> 力天电子lpc2148 GPIO之按键输入试验
STM32-串口实验学习笔记
USART1_IRQHandler(void)函数: 当串口1发生了相应的中断,就会跳到改函数执行。这里设计了一个小小的接收协议(系统并未定义):通过这个函数,配合一个数组USART_RX_BUF ,一个接收状态寄存器USART_RX_STA实现对串口的数据的接收管理。USART_RX_BUF 最大值为64,也就是一次接收的数据最大不能超过64字节。USART_RX_STA是一个接收状态寄存器,其各位的定义如表所示: (注意:这个是作者设计的协议,怎样判断串口接收一组数据完毕?由于每次接收的数据长度不一样,少的就3个8位数据,多的时候有十多个,这个数据个数是不定的,且没规律的数据,有什么好的方法让它接收完整? 协议的设
[单片机]
STM32-串口实验学习笔记
plc中断的作用是什么呢
  plc这样理解中断功能,在理解中断时,首先要清楚plc的运算周期或者说是扫描周期,有必要说下plc顺控循环执行的流程,这是理解中断的前提,必须要掌握,分为三部分,输入处理、程序处理、输出处理   1、输入处理,可编程控制器在执行程序前,将可编程控制器的所有输入端子的ON/OFF状态读入输入映像区,程序执行过程中即使输入发生变化,输入映像区的内容也不会变化,在执行下一个循环的输入处理时读取该变化。   2、程序处理、plc根据程序内存中的指令内容,从输入映像区和其他软元件的映像区中读出各软元件的ON/OFF状态,然后从0步依次开始运算,并将每次得出的结果写入到映像区中。因此,各软元件的映像区随着程序的执行逐步改变其内容,此外
[嵌入式]
plc<font color='red'>中断</font>的作用是什么呢
PIC单片机引脚中断程序的设计技巧
1 简 述 所有的中档系列PIC单片机,PORTB端口最高的4个引脚(RB7"RB4)在设为输入模式时,当输入电平由高到低或由低到高发生变化时,可以让单片机产生中断。这就是通常所说的引脚状态变化中断。 在设计引脚中断程序时,有三个需要特别注意的地方。一是,在清除P0RTB中断标志位RBIF之前,必须安排一条必不可少的,以PORTB端口数据寄存器PORTB为源寄存器的读操作指令。放置这一指令的目的有时并不只是为了读取有用的数据,而是为了取消状态变化的硬件信号,以便顺利清除RBIF标志位,为下一次中断做好准备。二是,由于端口PORTB是引脚电子变化中断,即无论引脚出现上升沿还是下降沿都会产生中断请求,所以必须处理好不需要的虚假
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved