1.1 中断源
LPC2000 系列的向量中断控制器(VIC )支持32 个中断请求输入,也即是支持32 个中断源,见表5.1 。这32 个中断按顺序称为VIC 通道0 ,VIC 通道1 ,… ,VIC 通道31 。
每一个VIC 通道都支持软件中断与硬件中断,即每个中断均可由软件或硬件中断产生,软件中断与对应通道上的硬件中断是逻辑“或”的关系。软件中断可通过置位VICSoftInt 寄存器相应位来产生,也可通过置位VICSoftIntClear 寄存器相应位来清除。
表5.1 外设功能的中断源
1.2 三种中断类型
LPC2000 具有3 类中断:FIQ 、向量IRQ 和非向量IRQ 。LPC2000 系列可通过对VICIntSelect 和VICVectCntlx (x=0,1,…,15 )这两类寄存器的设置,将以上的32 个中断源设置为这三类中断的任何一种。其中,
? 快速中断请求FIQ 具有最高优先级。建议只分配一个中断请求给FIQ 以减少中塅处理程序的延迟。当然,VIC 支持多个FIQ 中断。
? 向量IRQ 具有中等优先级。该级别最多可分配32 个请求中的16 个。32 个请求中的任何一个都可以分配到16 个向量IRQslot 中的任意一个。其中,slot0 具有最高优先级,而slot15 则为最低优先级。
? 非向量IRQ 具有最低优先级。
1.3 如何初始化某个中断源为三类中断中的一类
通过VICIntSelect 中断选择寄存器将32 个中断请求分配为FIQ 或IRQ (包括向量IRQ 与非向量IRQ );通过VICVectCntlx (x=0,1,…,15 )来选择32 个中断请求中的某个为向量IRQ 并设定此中断请求为IRQ slotx (x 对应于VICVectCntlx 中的x )。若某个中断源被设定为IRQ ,但却未通过VICVectCntlx 使能,则该中断源将被默认为非向量IRQ 。
1.4 中断处理过程中断处理过程如下所示:
? 初始化:设置中断源为3 种中断源之一,设置中断地址,使能中断,然后正常运行用户程序;
? 当有IRQ 中断产生时,VIC 将会根据中断源设置VICVectAddr 寄存器为相应中断服务程序的地址,切换处理器工作模式为IRQ 模式,并跳转到IRQ 中断入口0x00000018 处;
? 异常中断向量表中0x00000018 处使用“LDR PC, [PC, #-0xFF0] ”,使得程序跳转到(0x00000018+8-0x00000FF0=0xFFFFF030 )存储器处保存的地址。0xFFFFF030 是VICVectAddr 寄存器地址。也即是说:通过该指令,程序跳转到VICVectAddr 寄存器所指向的中断服务程序的地址;
? 中断服务程序执行相应的中断处理,清除中断。建议用__irq 关键字定义中断服务程序;
? 中断服务完成后,即可返回原中断点。返回时要同时切换处理器工作模式。
注意: 退出中断前,一定要对VICVectAddr 寄存器写0 ,通知VIC 中断结束;建议用__irq 关键字定义中断服务程序,这样的话,该函数将自动切换处理器工作模式,但该函数不能返回参数或者数值。
1.5 IRQ中断
IRQ 中断有向量IRQ 和非向量IRQ 中断两种类型,当IRQ 中断产生时:
? 若是向量IRQ 中断,由于之前VIC 已经将最高优先级请求的IRQ 服务程序地址VICVectAddrx(x=0,1,…,15) 装入VICVectAddr ,故程序跳入该中断服务程序继续执行。
? 若是非向量IRQ 中断,VIC 提供默认服务程序地址VICDefVectAddr ,IRQ 中断入口程序可通过读取VIC 的向量地址寄存器VICVectAddr 来取得该地址,然后跳转到相应服务程序继续执行。该默认服务程序由所有非向量IRQ 公用,默认服务程序可读取IRQ 状态寄存器以确定哪个IRQ 被激活。
1.6 关于外部中断
外部中断的设置除了与上述各种寄存器有关外,还与EXTINT 、EXTWAKE 、EXTMODE 和EXTPOLAR 等寄存器相关。
1.7 举例
1. 初始化外部中断3(EINT3) 为非向量中断,并设置为电平触发模式,然后等待外部中断。
PINSEL1 = 3<<8; // 设置管脚连接,P0.20 设置为EINT3
EXTMODE = 0x00; // 设置EINT3 中断为电平触发模式
/* 打开EINT3 中断( 使用非向量IRQ) */
VICIntSelect = 0x00000000; // 设置所有中断分配为IRQ 中断
VICDefVectAddr = (int)IRQ_Eint3; // 设置中断服务程序地址
EXTINT = 1<<3; // 清除EINT3 中断标志
VICIntEnable = 1<<17; // 使能EINT3 中断,EINT3 在Bit17 上
2. EINT3 的中断服务子程序
void __irq IRQ_Eint3(void) {
/*
用户添加
*/
/* 等待外部中断信号恢复为高电平( 若信号保持为低电平,中断标志会一直置位) */
while( (EXTINT&1<<3)!=0 ) {
EXTINT = 1<<3; // 清除EINT3 中断标志,1<<3 等价于 0x08
}
VICVectAddr = 0; // 向量中断结束
}
LPC2000
每一个VIC
LPC2000
? 快速中断请求FIQ
? 向量IRQ
? 非向量IRQ
1.3 如何初始化某个中断源为三类中断中的一类
通过VICIntSelect
1.4 中断处理过程中断处理过程如下所示:
? 初始化:设置中断源为3
? 当有IRQ
? 异常中断向量表中0x00000018
? 中断服务程序执行相应的中断处理,清除中断。建议用__irq
? 中断服务完成后,即可返回原中断点。返回时要同时切换处理器工作模式。
注意:
1.5 IRQ中断
IRQ
? 若是向量IRQ
? 若是非向量IRQ
1.6 关于外部中断
外部中断的设置除了与上述各种寄存器有关外,还与EXTINT
1.7 举例
1.
PINSEL1 = 3<<8; //
EXTMODE = 0x00; //
/*
VICIntSelect = 0x00000000; //
VICDefVectAddr = (int)IRQ_Eint3; //
EXTINT = 1<<3; //
VICIntEnable = 1<<17; //
2. EINT3
void __irq IRQ_Eint3(void) {
/*
用户添加
*/
/*
while( (EXTINT&1<<3)!=0 ) {
EXTINT = 1<<3; //
}
VICVectAddr = 0; //
}