ARM中断编程
-----------------------------------------------------------------------
Author :tiger-john
WebSite :blog.csdn.net/tigerjb
Email :[email protected]
开发板 : LPC220
环境 :ADS1.2,
Tiger声明:本人鄙视直接复制本人文章而不加出处的个人或团体,但不排斥别人转载tiger-john的文章,只是请您注明出处并和本人联系或留言给我。3Q
-------------------------------------------------------------------------
目录:
一. 前言
中断的基本概念:
1. 在ARM中最多有32个中断请求
2. 16个向量IRQ中断(16个向量中断的VIC中断号已经有系统定义好了。在p208中可查看)
(16个向量中断有16个优先级,可动态分配给中断请求)
3. 可产生软件中断。
4. 中断的优先级资源:中断的优先级资源就是CPU的中断系统。以ARM7体系的CPU为例,最多可以有32个中断资源。对于每个具体的中断源可以将其设定为FIQ,使其具有最高优先级,但FIQ 最好是分配给唯一的中断源,否则就失去意义;也可以设定为向量IRQ,使其具有中等优先级,但向量IRQ的总数不能超过16个,这些中断源优先级的高低按向量编号从0(最高)到15(最低)排序;如果中断源的个数超过17个,则剩余的中断源只能设定为非向量IRQ,其优先级最低。操作系统本身必须使用一个定时器中断源来作为系统节拍中断,它是操作系统工作的基础。
二VIC向量中断控制器
1. 向量中断控制器(VIC)具有32个中断请求输入
a. 可以将其分为3类:
FIQ,向量IRQ中断和非向量IRQ.
b. 快速中断请求(FIQ)要求具有最高优先级。当如果只有一个中断被分配为FIQ时,可现实最短的FIQ等待时间,因为FIQ服务程序只要简单地启动对该中断处理就可以了。
c. 向量IRQ中断具有中等优先级。该优先级可分配32个请求中的16个。32个请求中的任意一个都可以分配到16个向量IRQslot中的任意一个,其中slot()具有最高优先级,而slot15则为最低优先级。
d. 非向量IRQ中断的优先级最低。
2在编写中断程序时最常用的寄存器
a. 中断使能寄存器(VICIntEnable)
(1) VICIntEnable寄存器有32为:从0~31给每一位写1表示时该为对应的中断时能,写入0表示禁止该位的中断。(每一位对应的中断和VIC通道号对应。
Eg:VICIntEnable=1<<6;表示使UART0能中断,因为UART0对应的中断号即为6.
b. 中断选择寄存器VICIntSelect
(1) VICIntSelect:该寄存器有32位(0~31)将32个中断请求分别分配为FIQ或IRQ ,
(2) 给对应位写入1表示给对应的中断请求分配为FIQ
(3) 给对应位写入0表示给对应的中断请求分配为IRQ
C.向量控制寄存器0~15(VICVectCntl0~15)
(1)如果给一个中断指定的向量控制寄存器为VICVectl0则表示该中断具有最高中断优先级。反之,如果给一个中断指定的向量控制寄存器为VICVectl15则表示该中断具有最低优先级。
(2)VICVectCntlx(x指0~15)该寄存器为6位。
0~4:用来指定中断编号
5:为1表示向量使能
Eg;VICVectCntl0=0x20|6(表示给UART0分配向量控制寄存器,且它的优先级是最高的(0表示最高优先级)
D.向量地址寄存器(VICVectAddrx)
(1)当发生一个IRQ中断时,VIC会将对应的IRQ服务程序地址存入该寄存器,IRQ中断入口处的程序可读寄存器并跳转到读出的地址,执行相应的中断服务程序
(注:该寄存器应该在ISR快结束时执行一次些操作(写入的值一般为0)以遍更新优先级硬件。)
(2)在发生中断时,给中断分配中断地址时应该和给该中断分配的中断控制寄存器的号一致
Eg: VICVectCntl0=0x20|6;
VICVectAddr0=(uint32)UART0_IRQ(自己编写的终端函数的地址)
注:在编写向量中断程序时,必须对他进行初始化。一般的程序过程是:首先:用VICIntSelect寄存器对该中断进行选择时IRQ中断还是FIQ中断。
其次:用VICVectCntlx给该中断分配向量终端控制寄存器(其中x的值越小,中断优先级越高。
再次:用VICVectAddrx给该中断分配中断地址:
最后:用VICIntEnable使该中断使能:
程序事例:
VICIntSelect = 0x00000000; // 设置所有中断为IRQ中断
VICVectCntl0 = 0x26; // UART0中断分配到IRQ slot 0,即优先级最高
VICVectAddr0 = (int)IRQ_UART0; // 设置UART0向量地址
VICIntEnable = 0x00000040; // 使能UART0中断
三非向量中断:
1. 常用寄存器:
a中断使能寄存器(VICIntEnable)
VICIntEnable寄存器有32为:从0~31给每一位写1表示时该为对应的中断时能,写入0表示禁止该位的中断。(每一位对应的中断和VIC通道号对应。
Eg:VICIntEnable=1<<6;表示使UART0能中断,因为UART0对应的中断号即为6.
b中断选择寄存器VICIntSelect
(1) VICIntSelect:该寄存器有32位(0~31)将32个中断请求分别分配为FIQ或IRQ ,
(2)给对应位写入1表示给对应的中断请求分配为FIQ
(3)给对应位写入0表示给对应的中断请求分配为IRQ
注:以上和向量中断的用法一致,一下是不同点
c. 默认向量地址寄存器VICDefVectAddr
该寄存器保存了非向量IRQ中断服务程序IRQ的地址
注:在编写非向量中断程序时,必须对他进行初始化。一般的程序过程是:
a. 首先:用VICIntSelect寄存器对该中断进行选择时IRQ中断还是FIQ中断。
b. 其次:用VICDefVectAddr寄存器存放非向量中断的地址
c. 最后:用VICIntEnable使该中断使能
程序事例:
VICIntSelect = 0x00000000; // 设置所有中断为IRQ中断
VICDefVectAddr0 = (int)IRQ_UART0; // 设置UART0非向量中断的地址
VICIntEnable = 0x00000040; // 使能UART0中断
四综合:一个程序中既有向量中断和非向量中断
Eg;假设UART0和SPI0 产生中断请求,它们被分配为向量IRQ(UART0的优先级高于SPI0),而UARTI和I2C产生非向量IRQ,
程序:
VICIntSelect = 0x00000000; // 设置所有中断为IRQ中断
VICVectCntl0=0x26//UART0通道号为6优先级为0(最高)
VICVectCntl1=0x2A//SPI0通道号为10优先级为1
VICVectAddr0=(int)UART0_IRQ;
VICVectAddr1=(int)SPI0_IRQ;
VICDefAddr=//保存非向量UART1和I2C 终端服务的地址;
VICIntEnable=0x6c0//SPI0,I2C,UART1,UART0在bit10,bit9,bit7和bit6=1