ARM2200下的中断编程二

ARM中断程序之外部中断

 

----------------------------------------------------------------------

Author             :tiger-john
WebSite           :blog.csdn.net/tigerjb

Email               :[email protected]

开发板            :LPC220

环境                :ADS1.2

Tiger声明:本人鄙视直接复制本人文章而不加出处的个人或团体,但不排斥别人转载tiger-john的文章,只是请您注明出处并和本人联系或留言给我。3Q

-----------------------------------------------------------------------

目录:

ARM2200下的中断编程一

ARM2200下的中断编程二

ARM2200 下的中断编程三

 

四.ARM中断程序编写之外部中断

前言:VIC中断控制器定义了4个外部中断,中断号为EINT0(14),

EINT1(15),EINT2(16),EINT3(17)用来给用户进行编写外部中断(例如按键中断。。。)

1.     在编写外部中断事先要对引脚功能选择寄存器(PINSEL0)进行配置

(参照具体型号的ARM数据手册,此处以LPC2230进行配置)在LPC2230中:

Eg:PINSEL1 = 3<<8;      // 设置管脚连接,P0.20设置为EINT3

2第二部外部中断还要对外部中断方式寄存器(EXTMODE)进行配置来选择每个EINT脚是电平触发还是边沿触发

A.EXTMODE(外部中断方式寄存器):总共有8

0位:对第0位写入1表示对EINT0使用边沿触发,反之,写入0表示对EINT0使用电平触发。

1位:功能和上面相似只是对EINT1进行配置

2位:是对EINT2进行配置

3位:是对EINT3进行配置

4~7位:保留

EgEXTMODE = 1<<3; // 设置EINT3中断为边沿触发模式

EXTMODE = 0<<3;          // 设置EINT3中断为电平触发模式

3第三部外部中断还要对外部中断极性寄存器进行配置(EXTPOLAR)进行配置(在电平触发方式中,EXTPOLAR寄存器用来选择相应引脚是高电平或低电平有效。在边沿触发方式中,EXTPOLAR寄存器用来选择引脚上升沿或下降沿有效)

A EXTPOLAT(外部中断极性寄存器)总共有8

0位:是对EINT0进行配置,对该位写入1表示时表示

EINT0高电平或上升沿有效。反之,对该位写入0表示表示EINT0低电平或下降沿有效

1位:是对EINT1进行配置。功能和上面类似。

2位:是对EINT2进行配置。功能和上面类似

3位:是对EINT3进行配置。功能和上面类似

4~7位:保留位。

Eg:  EXTPOLAR = 0x00;     // 设置EINT3中断为下降沿触发

         EXTPOLAR = 0x00;// 设置EINT3中断为低电平有效

4.第四部配置中断选择寄存器VICIntSelect

功能和前面的类似

Eg; VICIntSelect = 0x00000000; // 设置所有中断分配为IRQ中断

5若外部中断为向量中断则对向量控制寄存器0~15(VICVectCntl0~15)

进行配置。若为非向量中断则此步骤可省掉。

Eg: VICVectCntl0 = 0x20|17; // 分配EINT3中断到向量中断0,0x20表示向量IRQ使能,1<<17表示EINT3VIC通道17

6配置外部中断服务程序的地址:

a.若为向量中断则配置向量地址寄存器(VICVectAddrx

a.     b.若为非向量中断则配置默认向量地址寄存器VICDefVectAddr

eg:  VICVectAddr0 = (int)IRQ_Eint3;      // 设置向量中断服务程序地址IRQ_Eint3(为函数名,可随意起)

VICDefVectAddr = (int)IRQ_Eint3;             // 设置非向量中断服务程序地址

7.清除外部中断标志

切记要在初始化时对EXTINT进行初始化。否则程序会进入异常。

配置外部中断标志寄存器(EXTINT)

A.    通过对EXINT寄存器写人1来将其清零来清除外部中断标志

B.     EXTINT总共有8

0位:是对EINT0进行配置,写入1对外部中断EINT0中断进行清除

1位:是对EINT1进行配置,写入1对外部中断EINT1中断进行清除。

2位:是对EINT2进行配置,写入1对外部中断EINT2中断进行清除。

3位:是对EINT3进行配置,写入1对外部中断EINT3中断进行清除。

4~7位:保留位.

Eg: EXTINT = 1<<3;              // 清除EINT3中断标志

8.对中断使能寄存器(VICIntEnable)进行配置

功能和前面说的类似

Eg: VICIntEnable = 1<<17; // 使能EINT3中断,EINT3VIC通道17

注:编写外部中断程序时初始化实例:

1.初始化外部中断3,用向量中断,为边沿触发。

PINSEL1 = 3<<8; // 设置管脚连接,P0.20设置为EINT3

EXTMODE = 1<<3;  // 设置EINT3中断为边沿触发模式

EXTPOLAR = 0x00;  // 设置EINT3中断为下降沿触发

VICIntSelect = 0x00000000;            // 设置所有中断分配为IRQ中断

VICVectCntl0 = 0x20|17;            // 分配EINT3中断到向量中断0

VICVectAddr0 = (int)IRQ_Eint3;    // 设置中断服务程序地址

EXTINT = 1<<3;        // 清除EINT3中断标志  ,次步不能少

VICIntEnable = 1<<17;  // 使能EINT3中断,EINT3VIC通道17

2.     初始化外部中断为EINT3,用非向量中断,为电平触发

PINSEL1 = 3<<8; // 设置管脚连接,P0.20设置为EINT3

EXTMODE = 0<<3; // 设置EINT3中断为电平触发模式

EXTPOLAR = 0x00; // 设置EINT3中断为低电平触发

VICIntSelect = 0x00000000;// 设置所有中断分配为IRQ中断

VICDefVectAddr = (int)IRQ_Eint3;       // 设置中断服务程序地址

EXTINT = 1<<3;              // 清除EINT3中断标志  ,次步不能少

VICIntEnable = 1<<17;  //使能EINT3中断,EINT3VIC通道17

注:1.在编写中断服务函数时,外部中断为电平触发和边沿触发有区别

3.     zlg模版中编写中断服务函数时,函数名的前缀是 __irq

函数实例:

1>用外部中断3,用向量中断,为边沿触发的中断服务函数的程序

void   __irq IRQ_Eint3(void)

{ 

    uint32  i;

    i = IO0SET;                                               // 读取当前B1控制值

    if( (i&BEEPCON)==0 )                          // 控制B1输出取反

    { 

        IO0SET = BEEPCON;

    }

    else

    {

        IO0CLR = BEEPCON;

   

              EXTINT = 1<<3;    // 清除EINT3中断标志,1<<3 等价于 0x08

               VICVectAddr = 0;   // 向量中断结束

  }               

中断函数实现的功能时当有按键按下时会蜂鸣。

注:1.每个中断服务函数的函数名前缀必须加__irq

2在中断服务程序最后要清除中断标志EXTINT = 1<<3,以及给VICVectAddr寄存器写入0

3.切记在初始化外部中断时也要对EXTINT引脚进行初始化,否则程序会出现异常。

  2>初始化外部中断为EINT3,用非向量中断,为电平触发

void   __irq IRQ_Eint3(void)

{ 

    uint32  i;

    i = IO0SET;                                                // 读取当前B1控制值

    if( (i&BEEPCON)==0 )                            // 控制B1输出取反

    { 

        IO0SET = BEEPCON;

    }

    else

    { 

        IO0CLR = BEEPCON;

    }

    /* 等待外部中断信号恢复为高电平(若信号保持为低电平,中断标志会一直置位) */

    while( (EXTINT&1<<3)!=0 )  

    { 

        EXTINT = 1<<3;         // 清除EINT3中断标志,

    }

VICVectAddr = 0;               // 向量中断结束

}

 

John哥说明:  

在用电平触发时在中断服务程序最后要清除中断标志时,要使用

  while( (EXTINT&1<<3)!=0 ) 

    { 

        EXTINT = 1<<3;         // 清除EINT3中断标志,

    }

(因为等待外部中断信号恢复为高电平(若信号保持为低电平,中断标志会一直置位)这一点和边沿触发有区别。 

 

注:

1.中断使能清零寄存器VICIntEnClr:那1位置1,则用来屏蔽该位的中断。

2.     当有多个中断源被设置为非向量IRQ中断时,需要在用户程序中识别中断源,并分别作出处理。所以非向量IRQ中断响应延时相对较长。

3.     中断状态寄存器:

a.如果使用了多个非向量IRQ中断或多个FIQ中断,那么在发生中断后要在程序中查找中断源。通过IRQ状态寄存器和FIQ状态寄存器可以了解到这些中断源的中断请求状态。

b. 任何在VIC中使能的中断都会把中断请求反映在“所有中断寄存器(VICRawIntr)中

c.所有中断状态寄存器(VICRawIntr:当某位为1时表示对应位的中断源产生中断请求。

d.FIQ状态寄存器(VICFIQStatus):当某位为1时表示对应位的中断产生FIQ中断请求。

e.IRQ状态寄存器(VICIRQStatus:当某位为1时表示对应位的中断源产生IRQ中断请求

你可能感兴趣的:(编程,IO)