麦片和燕麦片哪个好吃:一 ARM9(S3C2440)的中断系统——程序实例讲解

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 18:11:14

一  ARM9(S3C2440)的中断系统——程序实例讲解

(2011-08-05 12:42:57) 转载分类: ARM9裸机学习笔记

下面的程序讲解是基于FL2440开发板的程序讲解,有不对的地方希望大家能够指教

中断控制程序编写步骤

主程序

1.先清除中断源挂起寄存器( SRCPND SRCPND)和中断挂起寄存器( INTPND),可用 rSRCPND= rSRCPND 和rINTPND=rINTPND =来完成;
2.设中断模式,这里使用通用中断,rINTMOD=0x00000000因上电或复位时rINTMOD是清 0的,这步也可以不做。
3.I/O 口初始化,有些中断源要通过 I/O 口向 CPU 申请中断,如外部中断 0(EXTINT0通过 )F口的 GPF0 、外部中断11(EXTINT11)通过G口的 GPG3 向CPU 申请中断,此时两个口的控制寄存器 GPFCON 和GPGCON 的要设置成:GPFCON[1:0]=1,0;GPGCON[7:6]=1,0。
4设中断服务函数地址, S3C2410 在2410addr.h 中定义了 40个宏,设置了系统支持的中断服务函数的指针,设中断服务函数地址就是把我们编写的中断服务函数的地址(就是中断服务函数的名字)赋予相应的函数指针。每个中断源的中断服务函数指针名是固定的:pISR+中断源。

5.设中断触发方式,触发方式有 5种,有上升沿、下降沿、双沿、低电平、高电平触发方式,外部中断触发方式在外部中断控制寄存器 (EXTINTn)中设定。如 EINT0 触发方式在 EXTINT0[2:0] 中设定,[2:0]=000 低电平、 001 高电平、 01X 下降沿、 10X 上升沿、 11X 双沿触发,详见:http://blog.sina.com.cn/s/blog_6c73c98d0100t3l6.html

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设置为输出,连接了4个LED
 rGPBDAT|=0x560;//4个LED全灭
 rGPFCON &=~((3<<0)|(3<<4)|(3<<6)|(3<<8)) ;
 rGPFCON |= ((2<<0)|(2<<4)|(2<<6)|(2<<8)) ;//GPF0,GPF2,GPF3,GPF4工作在第二功能状态,即中断
 //rEXTINT0=0x0;
 rEINTPEND=(1<<4); //清外部中断挂起寄存器,清的是外部中断4
 ClearPending(BIT_EINT0|BIT_EINT2|BIT_EINT3|BIT_EINT4_7);//清外部中断0,2,3,4
 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){      //根据键值控制4个LED亮灭变化
  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;//没有该语句也能正常运行,可能是保证寄存器能清除的
}

关于中断暂时就想到这些,就先写这些吧