s3c2440裸机-异常中断(四. irq之外部中断)

发布时间:2023-08-09  

中断前:

中断产生后:

问题案例:
我们想实现一个按键点灯程序,我们知道有以下两种方案:

1.轮询方案:轮询检测按键的电平状态,当检测到被按下后,对应的gpio会拉低,点亮对应的led;(略)

2.中断方案:将按键配置成外部中断源,当有按键按下,触发中断,在中断服务程序(isr)中去完成点灯。


下面开始写代码:

一.中断初始化

1)中断源设置

我们用按键作为外部中断源,我们把按键对应的gpio配置成中断引脚,当按键按下,相应的gpio产生了电平跳变,就会触发外部中断。


我们想达到按下按键灯亮,松开按键灯灭这种效果(配成双边沿触发,按下的时候产生下降沿中断,进行点亮,松开产生上升沿中断,进行熄灭)。当然也可做成按一下点亮,再按一下熄灭的效果(设成单边沿触发,每来一次中断,对led电平进行一次取反)。


查看原理图如下:


我们从按键的原理图中得知,当按键没有按下时,接上拉电阻,那么按键为高电平状态。当按键按下时,电位被拉低,按键处于低电平状态。s2-s5分别对应GPF0,GPF2,GPG3,GPG11; D10-D12这3盏led所对应的gpio分别是GPF4,GPF5,GPF6.

那么我们让s2,s3,s4分别控制D10,D11,D12;s5对D10-D12同时控制(按下s5,同时点亮3个led)。

我们需要配置D10-D12的gpio为输出模式,s2-s4的gpio为外部中断模式。

打开芯片手册找到第九章 IO ports,找到对应的gpio控制寄存器,将对应的gpio配置成中断模式。

代码如下:

  1. 配置GPIO为中断引脚:

    GPG的一样,我就不放图片了。

 GPFCON &= ~((3<<0) | (3<<4)); //先把eint0和eint2这两个引脚清零

 GPFCON |= ((2<<0) | (2<<4));   //S2,S3被配置为中断引脚

 

 GPGCON &= ~((3<<6) | (3<<22));

 GPGCON |= ((2<<6) | (2<<22));   //S4,S5被配置为中断引脚


2.设置中断触发方式:

当电平从高变低时,此时表示按键按下,当电平由低变高,表示松开按键。不妨设置中断方式为双边沿触发,按下按键,触发下降沿中断,中断服务程序就可以去点亮led,反之,松开触发上升沿中断,就可以去熄灭led。


    EXTINT0 |= (7<<0) | (7<<8);     /* S2,S3 */

    EXTINT1 |= (7<<12);             /* S4 */

    EXTINT2 |= (7<<12);             /* S5 */


3.设置外部中断屏蔽寄存器EINTMASK:

从上图我们知道外部中断0-3是直接连接到中断控制器,而外部中断4-7、外部中断8-23还要经过EINTMASK,那么我们需要配置EINTMASK来打开中断的通道:

EINTMASK &= ~((1<<11) | (1<<19));    //打开外部中断通道


4.外部中断挂起寄存器EINTPEND:

当一个外部中断(EINT4-EINT23)发生后,那么相应的位会被置1, 所以中断结束后需要清除对应位。这个寄存器可以用来区分外部中断4-23的哪一个中断源。

2)中断控制器设置

我们先来看下中断控制器的总框图:

1.首先是SRCPND:用来表示哪个中断源发出了中断请求。

我们先看下中断源:

从上图我们发现外部中断有24个外部中断,除了外部中断EINT,还有定时器中断,ADC中断,UART中断等…。


我们来认识下SRCPND寄存器:(用来表示哪个(哪些)中断源已产生中断请求,中断结束后要清中断)

从上图中我们发现EINT4-7共用1bit,EINT8-23共用1bit,那么肯定有其他寄存器来区分它们,那就是EINTPEND寄存器(后面5会讲)。


2.然后到达INTMSK:(中断屏蔽寄存器)

我们需要把INTMSK寄存器配置成非屏蔽状态,默认是中断源时屏蔽的,见下图:

3.INTMOD(中断模式,是fiq还是irq)

4.Priroty:

5.INTPND:
INTPND 用来显示当前优先级最高的、正在发生的中断, 需要清除对应位。

中断发生后,SRCPND中会有bit置1,可能好几个(因为同时可能发生几个中断),这些中断会由优先级仲裁器选出一个最紧迫的,然后把INTPND中相应位置1。所以只有INTPND置1,CPU才会处理。

我们知道有可能同时出现多个中断请求,那么INTPND就挑选出当前优先级最高的、正在发生的中断。


当产生irq后,要去分辨是哪个中断源,根据不同的中断源去中断服务程序isr中做不同的事情,那么如何得知当前产生的中断是哪一个外部中断源产生的呢?那么就可以访问这个INTPND寄存器。


可是我们要去手工去解析INTPND里面的位,才能知道是哪个中断源产生了中断请求。那么有没有什么比较快捷的方式自动帮我们解析INTPND呢,直接返回中断号给我们?


当然有啦,有一个INTOFFSET寄存器的值就是代表哪个中断请求产生了,如果INTOFFSET=0表示EINT0产生了中断请求,INTOFFSET=2表示EINT2产生了中断请求。具体见下图:

我们从上图看到ENIT4-7共用一个offset, EINT8-23也共用一个offset,那么要通过访问EINTPEND寄存器来区分它们。

中断控制器设置代码入下

 GPFCON &= ~((3<<0) | (3<<4)); //先把eint0和eint2这两个引脚清零

 GPFCON |= ((2<<0) | (2<<4));   //S2,S3被配置为中断引脚

 

 GPGCON &= ~((3<<6) | (3<<22));

 GPGCON |= ((2<<6) | (2<<22));   //S4,S5被配置为中断引脚


3)中断总开关

CPSR有I位,是irq的总开关,我们需要把CPSR寄存器 bit7给清零,这是中断的总开关,如果bit7设置为1,CPU无法响应任何中断。

    /* 把bit7这一位清零 */

bic r0, r0, #(1<<7)  /* 清除I位, 使能中断 */

msr cpsr, r0


二. 中断服务程序设计

到这里中断前的初始化工作知识点就已经讲完了,当然要提前准备好led初始化工作(就是将led对应的gpio配置成输出模式,这个不讲解)。

那么中断产生后,我们之前讲过,会跳转到0x18异常向量,执行跳转指令ldr pc, =_irq,和之前的swi异常,und异常框架一样。
代码框架如下:

展开代码


1.我们在start.s中用汇编代码设置cpsr的I位,开启中断开关;

2.在main函数中初始化中断源key_eint_init,初始化中断控制器interrupt_init;

3.然后继续执行main主函数。

4.当中断产生,触发irq异常,进入0x18异常向量,执行do_irq。

do_irq实现如下(和之前的do_und, do_swi类似):


handle_irq_c函数实现如下:


void key_eint_irq(int irq)

{

unsigned int val = EINTPEND;

unsigned int val1 = GPFDAT;

unsigned int val2 = GPGDAT;

if (irq == 0) /* eint0 : s2 控制 D12 */

{

if (val1 & (1<<0)) /* s2 --> gpf6 */

{

/* 松开 */

GPFDAT |= (1<<6);

}

else

{

/* 按下 */

GPFDAT &= ~(1<<6);

}

}

else if (irq == 2) /* eint2 : s3 控制 D11 */

{

if (val1 & (1<<2)) /* s3 --> gpf5 */

{

/* 松开 */

GPFDAT |= (1<<5);

}

else

{

/* 按下 */

GPFDAT &= ~(1<<5);

}

}

else if (irq == 5) /* eint8_23, eint11--s4 控制 D10, eint19---s5 控制所有LED */

{

if (val & (1<<11)) /* eint11 */

{

if (val2 & (1<<3)) /* s4 --> gpf4 */

{

/* 松开 */

GPFDAT |= (1<<4);

}

else

{

/* 按下 */

GPFDAT &= ~(1<<4);

}

}

else if (val & (1<<19)) /* eint19 */

{

if (val2 & (1<<11))

{

/* 松开 */

/* 熄灭所有LED */

GPFDAT |= ((1<<4) | (1<<5) | (1<<6));

}

else

{

/* 按下: 点亮所有LED */

GPFDAT &= ~((1<<4) | (1<<5) | (1<<6));

}

}

}


EINTPEND = val; /* 清中断 : 源头*/

}


/*INTOFFSET中哪一位被设置成1,就表示哪一个 中断源*/

void handle_irq_c(void)

{

/* 分辨中断源 */

int bit = INTOFFSET;


/* 调用对应的处理函数 */

if (bit == 0 || bit == 2 || bit == 5)  /* eint0,2,bit==5还需细分eint8_23 */

{

key_eint_irq(bit); /* 处理中断, 清中断源EINTPEND(eint11,2 eint11, eint11) */

}


/* 清中断 : 从源头开始清 */

SRCPND = (1< INTPND = (1<}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    压前接法电路,功率表电压测量中包括负载的电压降和功率表电流回路的电压降两部分。后一部分与负载电流相互作用产生的功率即是功率表的方法误差△p。可用下式求取负载功率的实际值pf。损耗和功率单位为w。 pf=pb-ap......
    导线,当采样电流流经主电流回路时,其产生的磁场在霍尔电路上感应出相应的电信号,经过信号处理电路输出电压信号,使得产品输出严格地与被测电流值成比例。 线性......
    可将电流从4ma调整到20mA的电流回路测试仪;传感器是任何测量系统不可或缺的一部分,因为它们有助于将现实世界的参数转换为机器可以理解的电子信号。在工业环境中,常用......
    C2充电至完成,在C2上形成的电压加到T3 9014NPN三极管的基极b上;另一路经R5、R4也加到T3 9014NPN三极管的基极b上,并经T3 9014NPN三极管的基极b、发射极e、R3、接地构成电流回路......
    为应用F3L400R10W3S7 EasyPACK™ 3B三电平模块产品的双脉冲实测波形。可以看到在关断同样电流时,长换流回路中内管关断时的电压尖峰明显更大,因此就需要在设计应用过程中通过DPT评估恶劣工况下内管的电......
    通后,220V的正通过开关S、灯泡、VS回到220V的负形成灯泡供电电流回路,灯泡点亮发光至A2、A1端导通电压过0点。同时,C1上的电压通过R2、VD双向触发二极管、VS双向可控硅的G极、A1、电容......
    线圈或零点平衡线圈。 (2)电流回路电阻发生改变,电阻值变小时指针超过零位;电阻值增大时指针达不到零位。对此,应更换电流回路中的电阻。 (3)电压回路电阻发生改变,电阻值变大时指针超过零位;电阻值减小时指针达不到零位。对此......
    平均电流控制的原理是啥?平均电流降压电路设计简述;简 述 :**** 降压变换器的电流控制框架如图所示,采用的双回路控制,外环为电压回路,用以调整电压误差以及产生电流误差及产生电流内回路的电流......
    展了两条零电平换流路径,通过对零电平换流路径的选择和控制可以实现更均衡的损耗分布和更小的换流回路杂感。 3.1. 电流路径 ANPC在每个模态时的零电平换流有多条路径可供选择,根据调制算法的......
    计印制电路板的时候,应注意采用正确的方法。每一个开关电源都有四个电流回路: ◆ 电源开关交流回路 ◆ 输出整流交流回路 ◆ 输入信号源电流回路 ◆ 输出负载电流回路输入回路 通过一个近似直流的电流......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>