S3C2440开发板裸机程序系列08—中断控制

1.  概述

最近刚刚在TQ2440上面调通了ADXL345的I2C控制,可通过串口和TFT屏查看XYZ三个轴倾角变化,本来打算把TQ2440上面的I2C控制详细解说一下,但是还跳了2个知识点:中断和I2C协议。所以还要等我补充完这2个知识点再说。(I2C协议要从51单片机说起,后面总结时再谈吧)

从程序的执行过程来说,可以分为:正常执行,跳转执行(Arm汇编是B和BL指令,B指令不返回),中断处理。

从嵌入式控制的要求来说,一个嵌入式装置要完成大量的数据采集、数据变换、外设控制等功能,这些子功能的实现一般分为:查询方式和中断方式。显然中断方式可以提高处理器利用率,提高系统实时性。

S3C2440的中断包括快速中断FIQ和外部中断IRQ。因为FIQ模式有更多的私有寄存器,减少了模式切换过程中寄存器入栈和出栈的时间,所以FIQ执行效率更高。

通过INTMODE寄存器的设置,可以将某个中断定义为FIQ或者IRQ。如下图所示:

 INTMODE初始值默认是IRQ。这里只讲IRQ,并且不讨论中断优先级设置问题。

下面从中断源与中断屏蔽、中断函数和执行过程、中断编程例子等几个方面进行展开。 

2.  中断源与中断屏蔽

S3C2440处理器的中断处理流程见datasheet,如下。

入口,即中断源,有2种,with sub-register和without sub-register。

出口,也有2种,IRQ或FIQ,这个前面已经说过了。

对于with sub-register的中断源,需要先经过SUBMASK过滤。后面都要经过SRCPND,然后是MASK过滤,再然后是优先级Priority过滤到达INTPND,再送CPU处理。

S3C2440处理器的中断控制器支持60个中断源,如下:


中断的开关由几个寄存器来控制,并且初始状态(即默认)都是关闭的。先来了解一下都有哪些控制中断开关的寄存器设置。

经总结,共有4个地方设置中断的开与关:

a.当前程序状态寄存器CPSR和备份程序状态寄存器SPSR。在第6位和第7位,即F位控制FIQ中断是否允许响应,I位控制IRQ是否允许响应。这个寄存器设置主要是在启动程序中进行才有可能设置。用户编程可不考虑。

b.INTSUBMSK寄存器,它对应着上图的次级源这15个源,对应着设置INTSUBMSK[0:14],后面[15:31]没有用到。设置1是屏蔽,0是中断可用,初始都是1,即屏蔽状态。

c. INTMSK寄存器,它对应上图的这32个源,INTMSK[0:31]每个位对应一个。同理,设置1是屏蔽,0是中断可用,初始都是1,即屏蔽状态。

d.从上图的源和次级源的图中看出,EINT4_7和EINT8_23没有在次级源中,这么多外部中断源在次级源中也放不下了,所以又单独弄了个EINTMASK寄存器。在Datasheet中,这个寄存器没有在中断控制器Interrupt Controller中讲,而是放在了输入输出端口IO Ports中,如下图:

前4位保留,这样EINTn就和NINTMASK的位号对应上了。挺巧妙的。 

下面再说中断触发的标志,怎么体现出某个中断发生了呢?再看上面的中断处理流程图,有这2个寄存器:SRCPND和SUBSRCPND,如下图。它们的各位是指示各中断源是否发生中断的指示标志。只要有中断发生,对应的位就置1。

其实,还有1个专门外部EINT的设置,EINTPEND寄存器,该寄存器仍然是在输入输出端口IO Ports章节里讲的。同上面的EINTMASK一样,前4位没用,[4:23]各位对应着EINT4—EINT23.

SRCPND、SUBSRCPND和EINTPEND 有些区别,比如串口0的中断,对于接收和发送中断分别是INT_RXD0和INT_TXD0,这2个中断发生时,SUBSRCPND[0:1]这2位要置1,并且SRCPND[28]这1位也置1。再比如,对应ENIT5发生中断时,EINTPEND[5] 置1,SRCPND[4]也置1。

刚才提到的那3个屏蔽寄存器INTMSK、INTSUBMSK和EINTMASK,与挂起寄存器道理是一样的:2个地方都有的,必须2个地方都解除屏蔽,这个中断才真的可以使用了。 

3.  中断函数和执行过程

再看上面的中断处理流程图,如果某个中断没有屏蔽,发生中断后就会到达INTPND,这个寄存器某一位置1后,CPU就要进行处理了。中断挂起寄存器不再分源、次级源和外部中断,因此只1个寄存器--INTPND。它来告诉CPU有中断到来了。

总结一下这几个寄存器:

  • 中断屏蔽寄存器:INTMSK、INTSUBMSK和EINTMASK。有3个,分别对应源、次级源和外部中断,设置哪一位为0则哪一位就使能中断。

  • 中断源挂起寄存器:SRCPND、SUBSRCPND和EINTPEND。也有3个,分别对应源、次级源和外部中断,哪个源发生中断了,CPU就自动设置相应的位为1。

  • 中断挂起寄存器:INTPND。只有1个。具体确认是哪个中断发生了,还要查询SUBSRCPND和EINTPEND。

  • 此外:INTOFFSET寄存器。存的是0—31这个范围内的数值,对应着源的顺序号。这个主要是为了便于查询并进入相应的中断处理子程序中。

下面说中断处理的问题:

a.中断处理子程序做哪些必要的工作。

b.怎样自动处理中断处理子程序,包括进入和退出。

中断处理子程序必要的工作是:清中断标志位。这是为了下一次发生相同中断时还能处理,不是一锤子买卖。

怎样清中断? 哪一位置1了,就再置一次1。因此,SRCPND和INTPND必然是要清理的,此外SUBSRCPND和EINTPEND根据具体情况判断是否需要清理。

中断处理函数是特殊的子函数,因为它不需要在主函数中明确的调用。因此,使用ads中使用了关键字__irq 来表明这个函数是中断处理程序。__irq 发挥了下面2个主要作用:

a.中断发生时,自动保存所有需要保存的寄存器;

b.中断返回时,自动计数返回地址,自动进行CPSR寄存器状态的恢复。 

各类型的中断处理程序的入口地址是固定的,这个工作是启动程序中完成。入口地址就是一个32位的寄存器,这些32位寄存器里放的是中断处理函数的地址。因此,当编写完中断处理程序后,就需要把该程序的起始地址(或函数句柄)填写到那个32位寄存器中。

程序中这样处理:

pISR_EINT0 = (unsigned int)Eint0_Isr ;
pISR_EINT1 = (unsigned int)Eint1_Isr ;
pISR_EINT2 = (unsigned int)Eint2_Isr ;
pISR_EINT4_7 = (unsigned int)Eint4_7_Isr;

其中,pISR_EINT0,pISR_EINT1 ,pISR_EINT2 ,pISR_EINT4_7 是中断源入口地址,它是根据中断起始地址+偏移量,提前计算好的地址,放在2440addr.h文件供C源程序使用。

Eint0_Isr,Eint1_Isr,Eint2_Isr,Eint4_7_Isr 是编写的中断处理函数。 

4.  中断编程例子

两个例子:按键中断和定时器中断。

4.1按键中断

按键触发LED亮1秒钟。按键触发即外部中断触发,有高电平触发、低电平触发、边沿触发等,有EXINTn寄存器进行设置,这里采用默认值,即低电平触发。

如图所示,正好按下时为低电平,触发外部中断。

K1 -- EINT1 -- GPF1  
K2 -- EINT4 -- GPF4  
K3 -- EINT2 -- GPF2  
K4 -- EINT0 -- GPF0  

所以初始化时需要设置GPF0,GPF1,GPF2,GPF4为外部中断模式。

主程序做一些设置,然后就while(1);循环。

这些设置包括:Led和Key的GPIO状态设置,4个key中断位的使能中断设置,设置中断入口地址。 

4.2   定时器中断

定时器Timer0初始化为1秒钟一次。

主程序中定义一个全局变量flag(需要加volatile关键字),Timer0中断处理程序中引用这个flag外部变量,每隔1sec进入中断处理程序后,就将flag取反。主程序根据flag值,设置Led2的亮灭。

主程序如下: 

#include "ledflow.h"
#include "isrservice.h"
#include "timer.h"

void IO_Init(void) ;
volatile unsigned int flag = 0 ;
int Main()
{
	IO_Init() ;	
	while(1)
	{	
		if(flag ) 
		{	
			Led2_On() ;
		}
		else
		{
			Led2_Off() ;
		}
	} 
	return 0;	
}

void IO_Init(void)
{
	Led_Init() ;
	Timer0_Init() ;
	Timer0_Interrupt_Init() ;
	Isr_Init() ;
}

上述程序的完整代码:点击打开链接

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值