(转)ARM9(S3C2440)的中断系统——…

本文详细介绍了ARM处理器中断控制程序的编写步骤,包括清除中断挂起寄存器、设置中断模式、I/O口初始化等,并提供了具体的程序示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载地址:http://www.360doc.com/content/11/1123/11/7725999_166692855.shtml

中断控制程序编写步骤

主程序

1.先清除中断源挂起寄存器(SRCPND)和中断挂起寄存器(INTPND),可用 rSRCPND= rSRCPND rINTPND=rINTPND 来完成;

 SRCPND 寄存器包括 32 位,每位与一个中断源相关。如果相应的中断源产生中断请求且等待中断服务,则每个位置 1。因此这个寄存器指出那个中断源在等待请求服务。注意SRCPND 的每个位都由中断源自动置位,不管 INTMASK 寄存器的屏蔽位。此外,SRCPND寄存器不会受到中断控制器的优先级逻辑的影响。 

对于一个特定中断源的中断服务程序中,SRCPND寄存器的相应位必须被清除目的是下次能正确得到同一个中断源的中断请求。如果你从中断服务程序返回却没有清除该位,中断控制器将操作好像又有同一个中断源的中断请求到来。换言之,如果SRCPND的一个特殊位置 1,其总是认为一个有效的中断请求等待服务。

清除相应位的时间依赖于用户的需求。如果你想收到另一个来此同一个中断源的有效请求,你应该清除相应的位,然后使能中断。 

你可以通过写数据到这个寄存器来清除 SRCPND寄存器的某个位。你可以通过对相应位置 1 来清除相应位。如果你对相应位写 0,则该位的数值保持不变。 

 2.设中断模式,这里使用通用中断,rINTMOD=0x00000000因上电或复位时rINTMOD是清0的,这步也可以不做。 

中断模式寄存器 INTMOD 

该寄存器包括 32 位,每位与一个中断源相关。如果某位置 1,相应的中断将在FIQ模式下处理。否则在IRQ模式下操作。请注意仅有一个中断源能够在FIR模式下服务,也就是说,INTMOD仅有一个位可以被置 1 

 3.I/O 口初始化,有些中断源要通过I/O 口向 CPU 申请中断,如外部中断 0EXTINT0通过 F口的 GPF0 、外部中断11EXTINT11)通过G口的 GPG3 CPU 申请中断,此时两个口的控制寄存器 GPFCON GPGCON 的要设置成:GPFCON[10]=10GPGCON[76]=10 

4.设中断服务函数地址,S3C2410 2410addr.h 中定义了 40个宏,设置了系统支持的中断服务函数的指针,设中断服务函数地址就是把我们编写的中断服务函数的地址(就是中断服务函数的名字)赋予相应的函数指针。每个中断源的中断服务函数指针名是固定的:pISR+中断源。 

5.设中断触发方式,触发方式有 5种,有上升沿、下降沿、双沿、低电平、高电平触发方式,外部中断触发方式在外部中断控制寄存器 (EXTINTn)中设定。如 EINT0 触发方式在 EXTINT0[20] 中设定,[20]=000 低电平、 001 高电平、 01X 下降沿、 10X 上升沿、 11X 双沿触发, 

6.取消总中断屏蔽和子中断屏蔽,等待中断。例如通过 rEINTMASK rEINTMASK&=~(1<<11)

rINTMASK&=~(BIT_EINT0|BIT_EINT8_23);来实现。


中断服务程序

1.在中断服务程序中,先屏蔽中断,防止其他中断产生干扰我们中断服务程序的执行; 

2.执行中断服务程序;

3.清中断源挂起寄存器(SRCPND)和中断挂起寄存器(INTPND);

4.取消总中断屏蔽和子中断屏蔽,等待新中断产生; 

5.中断返回 

下面是具体的程序应用:

#include "2440addr.h"    //头文件,包含宏定义及清除挂起寄存器的ClearPending()函数 

static void __irq Key_ISR();//中断函数声明 

void delay(int x)//延时函数 

{ 

while(x) 

  {

   int k,j;

   for(k=0xff;k>0;k--)

    for(j=0xff;j>0;j--);

   x--;

  }

}

void ledMain(void)

{

rGPBCON = 0x1dd7fc; // GPB5,GPB6,GPB8,GPB10设置为输出,连接了4LED

rGPBDAT|=0x560;//4LED全灭

rGPFCON &=~((3<<0)|(3<<4)|(3<<6)|(3<<8)) ;

    rGPFCON |= ((2<<0)|(2<<4)|(2<<6)|(2<<8)) ;//GPF0GPF2GPF3GPF4工作在第二功能状态,即中断

 //rEXTINT0=0x0;

rEINTPEND=(1<<4); //清外部中断挂起寄存器,清的是外部中断4

    ClearPending(BIT_EINT0|BIT_EINT2|BIT_EINT3|BIT_EINT4_7);//清外部中断0234

    pISR_EINT0= pISR_EINT2 =pISR_EINT3 = pISR_EINT4_7=(int)Key_ISR;//设中断服务函数地址

    EnableIrq(BIT_EINT0|BIT_EINT2|BIT_EINT3|BIT_EINT4_7);//使能中断,即使INTMSK相应位为0

    rEINTMASK=~(1<<4); //使能外部中断4

    while(1);//等待中断发生

}

static void __irq Key_ISR()//中断服务函数,__irq用来声明通用中断函数

{

char key;//用来标识是哪一个按键按下

    unsigned int r;

    rINTMSK=0xffffffff;//这是屏蔽所有中断

    if(rINTPND==BIT_EINT0) {          //因为4个中断用的是同一个中断服务函数,所以判断 是哪一个中断发生

     ClearPending(BIT_EINT0);         //并清除挂起寄存器,获得键值

   key=1;

    }

    else if(rINTPND==BIT_EINT2) {

    ClearPending(BIT_EINT2);

    key=2; 

     }

     else if(rINTPND==BIT_EINT3) {

      ClearPending(BIT_EINT3);

      key=3;

     }

     else if(rINTPND==BIT_EINT4_7){

      rEINTPEND=(1<<4);

      ClearPending(BIT_EINT4_7); 

      key=4; 

     } 

     switch(key){      //根据键值控制4LED亮灭变化 

   case 1: 

     rGPBDAT^=(1<<5);

     break; 

   case 2:

     rGPBDAT^=(1<<6); 

     break; 

   case 3: 

     rGPBDAT^=(1<<8);

     break;

   case 4:

     rGPBDAT^=(1<<10);

     break;

      }

  EnableIrq(BIT_EINT0|BIT_EINT2|BIT_EINT3|BIT_EINT4_7);//再打开中断

}

下面在说一下用到的ClearPending()

该函数在头文件2440addr.h中:

__inline void ClearPending(int bit)//输入参数是相应位为1的值

{

  register i;//定义一个寄存器变量

  rSRCPND=bit;//向相应位置写1清除源挂起寄存器

  rINTPND = bit;//向相应位置写1清除源挂起寄存器

  i = rINTPND;//没有该语句也能正常运行,可能是保证寄存器能清除的

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值