ARM学习随笔(10)中断的学习
来源:互联网 发布:windows清理助手怎么样 编辑:程序博客网 时间:2024/06/05 08:55
LPC2000系列的向量中断控制器(VIC)支持32个中断请求输入,也即是支持32个中断源。这32个中断按顺序称为VIC通道0,VIC通道1,…,VIC通道31(实际上只使用了18个其他的预留)
每一个VIC通道都支持软件中断与硬件中断,即每个中断均可由软件或硬件中断产生,软件中断与对应通道上的硬件中断是逻辑“或”的关系。软件中断可通过置位VICSoftInt寄存器相应位来产生,也可通过置位VICSoftIntClear寄存器相应位来清除。
LPC2000具有3类中断:FIQ、向量IRQ和非向量IRQ。LPC2000系列可通过对VICIntSelect和VICVectCntlx(x=0,1,…,15)这两类寄存器的设置,将以上的32个中断源设置为FIQ和IRQ中断的任何一种(向量IRQ和非向量IRQ和在一起)。其中,快速中断请求FIQ具有最高优先级。建议只分配一个中断请求给FIQ以减少中断处理程序的延迟。当然,VIC支持多个FIQ中断。
向量IRQ具有中等优先级。该级别最多可分配32个请求中的16个。32个请求中的任何一个都可以分配到16个向量IRQslot中的任意一个。其中,slot0具有最高优先级,而slot15则为最低优先级。
非向量IRQ具有最低优先级。一般也只分配一个中断源。
VIC中断设置步骤(前两步是外部中断必需的,而内部中断如定时器中断则不用设置!!):
在初始化程序中:
一、管脚功能选择
PINSEL0
二、外部中断寄存器的4个寄存器的设置(其中EXTINT标志寄存器因为是达到要求自动置位,所以初始不用设置。当一个管脚选择使用外部中断功能时,对应在 EXTPOLAR 和EXTMODE 寄存器中的
位选择的电平或边沿将置位EXTINT 寄存器的中断标志。这样来向VIC 提出中断请求,如
果管脚中断使能,则产生中断。
通过向EXTINT 寄存器的位EINT0~位EINT3 写入1 来将其清零
往这个位置写1,该位置的值就变成0了,写0就保持不变,不管写前是1还是0,很多IC的寄存器是这么设置的,这是内部结构规定的。。电平激活方式下,
该操作只有在管脚处于无效状态时才有效。
电平激活方式下,如果管脚的EINT0 功能被选用且管脚处于有效状态时,
该位置位;边沿激活方式下,如果管脚的EINT0 功能被选用且管脚上出
现所选边沿时,该位置位。
有2 个I/O 口可选择用作EINT0 功能 (见“管脚配置”中有关P0.1 和P0.16
的描述)。
该位通过写入1 清除,但电平激活方式下管脚处于有效状态的情况除外
(例如,如果选择EINT0 为低电平激活且低电平在相应的管脚上出现时,
该位不能被清除;只有该管脚上的信号变为高电平时该位才能被清除 写入1以后EINT0是清零了,但是管脚还为低电平,处于有效状态,EINT0又置位了。)
一旦EINT0~EINT3 中的一位被置位并开始执行相应的代码(处理唤醒和/或外部中
断),该位必须清零。否则EINT 管脚刚触发的事件以后将不会被识别。
重要:只要执行外部中断操作模式(也就是,激活电平/边沿)的变化(包括外部中断
的初始化),那么EXTINT 寄存器中相应的位必须被清零!详细内容请见3.5.4 节“外部中
断方式寄存器(EXTMODE – 0xE01F C148)”和3.5.5 节“外部中断极性寄存器(EXTPOLAR –
0xE01F C14C)”。
例如,如果外部中断0 管脚的低电平将系统从掉电模式唤醒,为了将来还能进入掉电模
式,唤醒后的程序必须将EINT0 位复位。如果EINT0 位仍保持置位状态,后来唤醒掉电模
式的任何操作都将失败。外部中断处理也不例外。)
INTWAKE=0X00;//不作为唤醒用,为1时处理器从掉电模式唤醒
EXTMODE =0x00;// 为0用电平激活,为1时是边沿激活
EXTPOLAR=0x00;//为低电平或下降沿有效
三、VIC的设置
1、设置VICIntSelect
通过VICIntSelect中断选择寄存器将32个中断请求分配为FIQ或IRQ(包括向量IRQ与非向量IRQ)
相应位为1是FIQ,为0是IRQ。
例如:VICIntSelect = 0x00000000,设置所有中断都是IRQ
2、设置VICVectCntlx(仅对于IRQ,FIQ不需要此设置) 选择VIC通道slot并使能slot
通过VICVectCntlx(x=0,1,…,15)来选择32个中断请求中的某个为向量IRQ并设定此中断请求为IRQ slotx(x对应于VICVectCntlx中的x)。若某个中断源被设定为IRQ,但却未通过VICVectCntlx使能,则该中断源将被默认为非向量IRQ。
例如:VICVectCntl0 = 0x20(0x20是16进制数) | 14(14由于前面没有0x就是一个十进制数,他们俩可以或),设置EINT0为向量中断,使用Slot0。其中0x20是因为VICVectCntlx寄存器第5位是使能(由表知),14是通过下表得到的EINT0的VIC通道号(便于MCU识别是谁的中断请求)。
3、设置VICVectAddrx(仅对于IRQ,FIQ不需要此设置) 选择跳转中断服务程序地址(其中VICVectAddr=0;表示中断结束)
当有IRQ中断产生时,VIC将会根据中断源设置VICVectAddr寄存器为相应中断服务程序的地址,切换处理器工作模式为IRQ模式,并跳转到IRQ中断入口0x00000018处;
异常中断向量表中0x00000018处使用“LDR PC, [PC, #-0xFF0]”,使得程序跳转到(0x00000018+8-0x00000FF0=0xFFFFF030)存储器处保存的地址。0xFFFFF030是VICVectAddr寄存器地址。也即是说:通过该指令,程序跳转到VICVectAddr寄存器所指向的中断服务程序的地址。
例如:VICVectAddr0 = (uint32)EINT1_Exception,设置EINT1中断地址。EINT1一般是中断服务程序函数名即服务中断服务程序的首地址,前面要用(uint32)强制类型转换。
4、设置VICDefVectAddr(当都设置为向量IRQ时可以没有这个)
若是非向量IRQ中断,VIC提供默认服务程序地址VICDefVectAddr,IRQ中断入口程序可通过读取VIC的向量地址寄存器VICVectAddr来取得该地址,然后跳转到相应服务程序继续执行。该默认服务程序由所有非向量IRQ公用,默认服务程序可读取IRQ状态寄存器以确定哪个IRQ被激活。
例如:VICDefVectAddr = (uint32)Default_Entry,设置非向量中断地址。如果在管理向量中断的VICVectCntl0~15和VICVectAddr0~15中没有设置某一个中断EINTx则此EINTx中断发生时,要进入非向量中断处理程序Default_Entry。
5、 EXTINT=0X01;//通过向 EXTINT 寄存器 写入 1 来将其清零 定时器也是写入1清零
6、设置VICIntEnable使能,使能IRQ或FRQ
例如:VICIntEnable = 0x00018000,使能EINT1和EINT2。因为EINT1和EINT2的VIC通道号分别为15和16,所以15和16两位置一将EINT1和EINT2使能。
在中断服务程序中:
1、清除相应的中断标志,以响应下一次中断,并切换处理器工作模式。建议用__irq关键字定义中断服务程序(void __irq IRQ_Eint0 (void)),这样的话,该函数将自动切换处理器工作模式,但该函数不能返回参数或者数值。 EXTINT=0X01;//通过向 EXTINT 寄存器 写入 1 来将其清零。
2、中断处理程序。用户自己编写的实现某种功能的中断程序。
3、退出中断前,一定要对VICVectAddr寄存器写0,通知VIC中断结束 //中断程序结束时对向量地址寄存器执行 写 “0”操作
【在公共中断处理函数中
__irq __arm void irq_handler (void) //公共中断处理函数,检查 VICVectAddr 是否为空
{
void (*interrupt_function)();
unsigned int vector;
/***********当只有一个中断源时可以这样处理*************************/
vector = VICVectAddr; // Get interrupt vector.
//如果作为非向量中断,这里把 VICDefVectAddr 赋给 vector 和把 VICVectAddr 赋给 vector 都可以,
//因为当发生非向量中断时处理器自动把 VICDefVectAddr 赋给 VICVectAddr
interrupt_function = (void(*)())vector;
if(interrupt_function !=NULL){
interrupt_function(); // Call vectored interrupt function.
}else{
VICVectAddr = 0; // Clear interrupt in VIC.
}
/*********当只有一个中断源时可以这样处理*************************/
// 当有多个中断时可以通过读 VICIRQStatus 寄存器来判断是哪个中断产生了,并跳转到相应的处理函数
}
具体FIQ、向量IRQ和非向量IRQ的具体设置步骤不完全相同
1、快速中断FIQ
⑴在主程序中:
1、在VICIntSelect中将中断分配为FIQ中断;
2、在VICIntEnable中使能外设中断。
⑵中断服务程序中:
1、中断处理程序;
2、清除相应的中断标志,以响应下一次中断。
2、向量IRQ
⑴主程序
1、在VICIntSelect中将中断分配为IRQ中断;
2、在VICVectCntlx中分配中断通道(优先级);
3、在VICVectAddrx中设置中断服务程序的地址;
4、通过VICIntEnable使能外设中断。
⑵中断服务程序
1、中断处理;
2、清除相应的中断标志,以响应下一次中断;
3、对VICVectAddr寄存器执行写操作(通常为0x00),结束向量中断。
3、非向量IRQ
⑴主程序
1、在VICDefVectAddr中设置中断服务程序的地址;
2、通过VICIntEnable使能外设中断。
⑵中断服务程序
1、中断处理;
2、清除相应的中断标志,以响应下一次中断;
3、对VICVectAddr寄存器执行写操作(通常为0x00),结束向量中断。
完整代码:
#include<lpc213x.h>
#include<stdio.h>
#define EINT0 14
#define led 1<<16
#define uint unsigned int
void __irq KeyIntr (void)
{
uint i;
i = IO1PIN; /* 读取当前IO1管脚 */
if ((i & led) == 0)
IO1SET = led;
else
IO1CLR = led;
/* 等待外部中断信号恢复为高电平
若信号保持为低电平,中断标志会一直置位。*/
while ((EXTINT & 0x01) != 0)
{
EXTINT = 0x01;/* 清除EINT0中断标志*/
}
VICVectAddr = 0;/* 向量中断结束*/
}
void init()
{
/*****************第一步***********/
PINSEL1=0x00000001; //P0.16选择为ENT0 但ENT0的值不是P0.16,只不过P0.16选择了ENT0功能。在P0.16为有效状态是ENT0才置位。
/*****************第二步***********/
INTWAKE=0; //不作为唤醒使用
EXTMODE=0; //电平方式触发
EXTPOLAR=0;//低电平触发
/*****************第三步***********/
VICIntSelect = 0x00000000;/* 设置所有中断分配为IRQ中断*/
VICVectCntl0 = 0x20 | EINT0;/* 分配中断编号,使能IRQ*/
VICVectAddr0 = (uint)KeyIntr;/* 设置中断服务程序地址*/
EXTINT = 0x01;/* 清除EINT0中断标志*/
VICIntEnable = 1 << EINT0;
}
int main()
{
PINSEL2 = 0x00000000;// 管脚连接GPIO
IO1DIR = led;/* 设置led控制口为输出,其余输入。*/
IO1SET = led;
init();
// IRQEnable();/*IAR使能IRQ中断 在VICVectCntl0的第5位以控制使能,所以可以不写*/
while (1); /* 等待中断 */
}
- ARM学习随笔(10)中断的学习
- ARM学习随笔(11)中断学习深入之按键去抖
- 中断下ARM的学习
- ARM学习随笔(12)定时器查询方式和中断方式
- ARM学习随笔(3)datasheet的重要性
- ARM学习随笔(8)LPC2132GPIO的理解
- ARM学习随笔(13)UART的理解
- ARM学习随笔(16)定时器的使用
- arm中断学习
- ARM学习笔记---中断
- ARM学习随笔(1) 位操作
- ARM学习随笔(4)芯片选择
- 十.ARM裸机学习之中断系统1(S5PV210的中断系统详解)
- ARM中断体系结构-学习笔记
- 嵌入式学习之ARM中断
- ARM学习之中断体系结构
- 汇编语言学习笔记(随笔记) 内部中断
- ARM学习随笔(5)datasheet阅读技巧
- mysql编码选择注意事项
- socket通信
- cookie妙用1——頁面間傳值
- 杭电 2030 汉字统计 (汉字机内码 存储方式)
- HDU 2152 Fruit【带上下界母函数】
- ARM学习随笔(10)中断的学习
- poj_1144/uva_315/zoj_1311 Network(割點模板題)
- myeclipse一直停留在Loading workbench界面上的处理办法
- HDU-2112-最短路(map)
- 完全符合能量守恒,胡克定理的JavaScript弹簧振子(超简洁版,超越第一版!)
- [LeetCode] Swap Nodes in Pairs
- BOJ 416. 丁神去谷歌
- 关于Jdk1.5特性 -----黑马程序员
- 还有的是封闭式的方式的合肥市