×
单片机 > 单片机程序设计 > 详情

MICRO2440 中断学习

发布时间:2020-08-31 发布时间:
|

S3C2440A 中的中断控制器接受来自60 个中断源的请求,部分中断源附带子中断源,他们共用一个中断源。两类中断:IRQ中断和FIQ中断,每一个中断都可以设为IRQ或FIQ,IRQ中断还需经过优先级判决器判定中断流程:以带子中断源的中断有中断为例:带子中断源的中断有中断长生,则子中断源请求寄存器(SUBSRCPND)相应位被置1,该位表明了是哪个子中断源长生的中断,然后看看该中断是否被屏蔽,该屏蔽由子中断屏蔽寄存器(SUBMASK)设置,然后源中断请求寄存器(SRCPND)相应为被置1,该位表明了是哪个中断源长生的,然后看看该中断是否被屏蔽,由中断屏蔽寄存器(MASK)设置,然后再看该中断被设为IRQ还是FIQ,该设置由中断模式寄存(MODE)设置,IRQ中断的话,还要看它的优先级,由优先级寄存器设定,最后得出优先级高的那个中断,在最终的中断请求寄存器(INTPND)中,相应的位被置1,最后等待着CPU响应中断。中断的清除顺序:首先清除SUBSRCPND,然后SRCPND,最后INTPND,清除标志位只须往相应的位写1即可中断优先级每个仲裁器的1 位仲裁器模式控制(ARB_MODE)和选择控制信号(ARB_SEL)的2 位控制优先级,如下:– 如果ARB_SEL 位为00b,优先级顺序为REQ0、REQ1、REQ2、REQ3、REQ4 和REQ5。– 如果ARB_SEL 位为01b,优先级顺序为REQ0、REQ2、REQ3、REQ4、REQ1 和REQ5。– 如果ARB_SEL 位为10b,优先级顺序为REQ0、REQ3、REQ4、REQ1、REQ2 和REQ5。– 如果ARB_SEL 位为11b,优先级顺序为REQ0、REQ4、REQ1、REQ2、REQ3 和REQ5。REQ0 的优先级总是最高并且REQ5 的优先级总是最低。通过改变ARB_SEL 位,可以轮换REQ1 到REQ4 的顺序。如果ARB_MODE 位被设置为0,ARB_SEL 位不能自动改变,这使得仲裁器操作在固定优先级模式中如果ARB_MODE 1,ARB_SEL 位会被轮换方式而改变,例如如果REQ1 被服务,ARB_SEL 位被自动改为01b 以便REQ1 进入到最低的优先级。ARB_SEL 改变的详细结果如下:– 如果REQ0 或REQ5 被服务,ARB_SEL 位不会改变– 如果REQ1 被服务,ARB_SEL 位被改为01b。– 如果REQ2 被服务,ARB_SEL 位被改为10b。– 如果REQ3 被服务,ARB_SEL 位被改为11b。– 如果REQ4 被服务,ARB_SEL 位被改为00b。IRQ类型的中断优先级,FIQ不存在,从上倒下,优先级依次降低中断向量:#define _RAM_STARTADDRESS  0x30000000#define _ISR_STARTADDRESS  0x33ffff00     #define _MMUTT_STARTADDRESS 0x33ff8000#define _STACK_BASEADDRESS 0x33ff8000#define HEAPEND    0x33ff0000#define _NONCACHE_STARTADDRESS 0x31000000#define pISR_RESET (*(unsigned *)(_ISR_STARTADDRESS+0x0))#define pISR_UNDEF (*(unsigned *)(_ISR_STARTADDRESS+0x4))#define pISR_SWI (*(unsigned *)(_ISR_STARTADDRESS+0x8))#define pISR_PABORT (*(unsigned *)(_ISR_STARTADDRESS+0xc))#define pISR_DABORT (*(unsigned *)(_ISR_STARTADDRESS+0x10))#define pISR_RESERVED (*(unsigned *)(_ISR_STARTADDRESS+0x14))#define pISR_IRQ (*(unsigned *)(_ISR_STARTADDRESS+0x18))#define pISR_FIQ (*(unsigned *)(_ISR_STARTADDRESS+0x1c))#define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20))#define pISR_EINT1 (*(unsigned *)(_ISR_STARTADDRESS+0x24))#define pISR_EINT2 (*(unsigned *)(_ISR_STARTADDRESS+0x28))#define pISR_EINT3 (*(unsigned *)(_ISR_STARTADDRESS+0x2c))#define pISR_EINT4_7 (*(unsigned *)(_ISR_STARTADDRESS+0x30))#define pISR_EINT8_23 (*(unsigned *)(_ISR_STARTADDRESS+0x34))#define pISR_CAM (*(unsigned *)(_ISR_STARTADDRESS+0x38))#define pISR_BAT_FLT (*(unsigned *)(_ISR_STARTADDRESS+0x3c))#define pISR_TICK (*(unsigned *)(_ISR_STARTADDRESS+0x40))#define pISR_WDT_AC97 (*(unsigned *)(_ISR_STARTADDRESS+0x44))   #define pISR_TIMER0   (*(unsigned *)(_ISR_STARTADDRESS+0x48))#define pISR_TIMER1   (*(unsigned *)(_ISR_STARTADDRESS+0x4c))#define pISR_TIMER2 (*(unsigned *)(_ISR_STARTADDRESS+0x50))#define pISR_TIMER3 (*(unsigned *)(_ISR_STARTADDRESS+0x54))#define pISR_TIMER4 (*(unsigned *)(_ISR_STARTADDRESS+0x58))#define pISR_UART2 (*(unsigned *)(_ISR_STARTADDRESS+0x5c))#define pISR_LCD (*(unsigned *)(_ISR_STARTADDRESS+0x60))#define pISR_DMA0 (*(unsigned *)(_ISR_STARTADDRESS+0x64))#define pISR_DMA1 (*(unsigned *)(_ISR_STARTADDRESS+0x68))#define pISR_DMA2 (*(unsigned *)(_ISR_STARTADDRESS+0x6c))#define pISR_DMA3 (*(unsigned *)(_ISR_STARTADDRESS+0x70))#define pISR_SDI (*(unsigned *)(_ISR_STARTADDRESS+0x74))#define pISR_SPI0 (*(unsigned *)(_ISR_STARTADDRESS+0x78))#define pISR_UART1 (*(unsigned *)(_ISR_STARTADDRESS+0x7c))#define pISR_NFCON (*(unsigned *)(_ISR_STARTADDRESS+0x80))#define pISR_USBD (*(unsigned *)(_ISR_STARTADDRESS+0x84))#define pISR_USBH (*(unsigned *)(_ISR_STARTADDRESS+0x88))#define pISR_IIC (*(unsigned *)(_ISR_STARTADDRESS+0x8c))#define pISR_UART0 (*(unsigned *)(_ISR_STARTADDRESS+0x90))#define pISR_SPI1 (*(unsigned *)(_ISR_STARTADDRESS+0x94))#define pISR_RTC (*(unsigned *)(_ISR_STARTADDRESS+0x98))#define pISR_ADC (*(unsigned *)(_ISR_STARTADDRESS+0x9c))//中断处理程序,以__irq标明

void __irq IicISR(void)

{

       rSRCPND |= 0x1<<27;

       rINTPND |= 0x1<<27;

       flag = 0;                //清标志

}


//中断处理程序与中断源的并联


pISR_UART0 = (U32)uartISR;

       pISR_IIC = (U32)IicISR;








1,系统默认分配那几个向量地址

A,当然第一个是复位,复位程序那里禁用掉看门狗,设置各个中断模式的SP位置

注意:调用C函数,首先要设置好堆栈,例如main函数。

B,其他几个中断向量入口地址,当发生相应的中断后,系统自动跳到相应的入口地址处

2,中断处理程序:

a)      计算返回地址

b)      保护现场,压入那个模式的堆栈

c)       中断处理

d)      清除中断标志

e)       恢复现场

f)        中断返回

     

.global _start

_start:    

    b   Reset

HandleUndef:

    b   HandleUndef

 HandleSWI:

    b   HandleSWI

HandlePrefetchAbort:

    b   HandlePrefetchAbort

HandleDataAbort:

    b   HandleDataAbort

HandleNotUsed:

b   HandleNotUsed

HandleIRQ:

    b   HandleIRQ

HandleFIQ:

    b   HandleFIQ

 

Reset:                 

    ldr sp, =4096           @ 设置栈指针,因为以下都是C函数   bl  disable_watch_dog   @ 关闭看门狗否则CPU会不断重启

    msr cpsr_c, #0xd2       @ 进入中断模式

    ldr sp, =3072           @ 设置中断模式栈指针

    msr cpsr_c, #0xd3       @ 进入管理模式

    ldr sp, =4096           @ 设置管理模式栈指针,

                       @ 其实复位之后,CPU就处于管理模式,

    bl  init_led            @ 初始化LED的GPIO管脚

    bl  init_irq            @ 调用中断初始化函数,在init.c中

    msr cpsr_c, #0x53       @ 设置I-bit=0,开IRQ中断

   

    ldr lr, =halt_loop      @ 设置返回地址

    ldr pc, =main           @ 调用main函数

halt_loop:

    b   halt_loop

 

HandleIRQ:

    sub lr, lr, #4                  @ 计算返回地址

    stmdb   sp!,    { r0-r12,lr }   @ 保存使用到的寄存器

                             @ 注意,此时的sp是中断模式的sp

@ 初始值是上面设置的3072

    ldr lr, =int_return  @ 设置调用EINT_Handle函数的返回地址 

    ldr pc, =EINT_Handle   @ 调用中断服务函数在interrupt.c中

int_return:

    ldmia   sp!,    { r0-r12,pc }^  @ 中断返回, ^表示将spsr的值复制到cpsr

   

void EINT_Handle()

{

    unsigned long oft = INTOFFSET;

    unsigned long val;

    switch( oft )

    {

        // S2被按下

case


关键字:MICRO2440  中断学习 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
8051单片机的函数发生器的设计