单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:3180|回复:0

ARM历程九-ARM中断

[复制链接]
ID:71259发表于 2014-12-29 20:01|显示全部楼层
   离上次真正写历程已经有10天的时间了。国庆嘛,自己给自己放了几天假——耍耍游戏下下棋什么的。
   其实这次写触屏的驱动和对ARM中中断的过程的了解也花了不少时间和脑力。
我就简单分享一下CPU执行某个中断的条件吧,也是我自己的理解,如果有错还请大家指正(以IRQ中断为例吧):
  
  在程序状态寄存器中(CPSR寄存器)i 位为IRQ中断禁止位,若这一位置1那么所有的IRQ中断都不会被CPU响应,如果这一位被清0,CPU也不一定会响应某一个或某些中断(就像是一个总开关)。所以,要想让CPU执行IRQ中断,CPRS中的i位必须要清0!
  在2440的CPU中还有两个中断屏蔽寄存器:INTMSK(中断屏蔽寄存器)和INTSUBMSK(子中断屏蔽寄存器)。如果相应的屏蔽位置1,寄存器指出某个中断无效。如果INTMSK 的一个中断屏蔽位是0,中断将被正常的服务。
   2440一共有60个中断源,某些中断源又有N个子中断,如:INT_UART0中断,它下面就还有INT_RXD0,INT_TXD0,INT_ERR0三个了中断源。要让CPU执行INT_RXD0的中断服务就要让INTMSK和INTSUBMSK中对应位清0!


   有这么多的中断源,那么CPU中怎么知道那个中断源发生中断了呢?原来在主函数中有这么一句:pISR_ADC = (int)AdcTsAuto; AdcTsAuto是中断服务函数的函数名!pISR_ADC在2440addr.h中定义了的(看最后一行):
#define pISR_EINT0       (*(unsigned *)(_ISR_STARTADDRESS+0x20))
#define pISR_EINT1       (*(unsigned *)(_ISR_STARTADDRESS+0x24))
#define pISR_EINT2       (*(unsigned *)(_ISR_STARTADDRESS+0x28))
#define pISR_EINT3       (*(unsigned *)(_ISR_STARTADDRESS+0x2c))
#define pISR_EINT4_7   (*(unsigned *)(_ISR_STARTADDRESS+0x30))
#define pISR_EINT8_23   (*(unsigned *)(_ISR_STARTADDRESS+0x34))
#define pISR_CAM       (*(unsigned *)(_ISR_STARTADDRESS+0x38))       // Added for 2440.
#define pISR_BAT_FLT   (*(unsigned *)(_ISR_STARTADDRESS+0x3c))
#define pISR_TICK       (*(unsigned *)(_ISR_STARTADDRESS+0x40))
#define pISR_WDT_AC97       (*(unsigned *)(_ISR_STARTADDRESS+0x44))//Changed to pISR_WDT_AC97 for 2440A
#define pISR_TIMER0       (*(unsigned *)(_ISR_STARTADDRESS+0x48))
#define pISR_TIMER1       (*(unsigned *)(_ISR_STARTADDRESS+0x4c))
#define pISR_TIMER2       (*(unsigned *)(_ISR_STARTADDRESS+0x50))
#define pISR_TIMER3       (*(unsigned *)(_ISR_STARTADDRESS+0x54))
#define pISR_TIMER4       (*(unsigned *)(_ISR_STARTADDRESS+0x58))
#define pISR_UART2       (*(unsigned *)(_ISR_STARTADDRESS+0x5c))
#define pISR_LCD       (*(unsigned *)(_ISR_STARTADDRESS+0x60))
#define pISR_DMA0       (*(unsigned *)(_ISR_STARTADDRESS+0x64))
#define pISR_DMA1       (*(unsigned *)(_ISR_STARTADDRESS+0x68))
#define pISR_DMA2       (*(unsigned *)(_ISR_STARTADDRESS+0x6c))
#define pISR_DMA3       (*(unsigned *)(_ISR_STARTADDRESS+0x70))
#define pISR_SDI       (*(unsigned *)(_ISR_STARTADDRESS+0x74))
#define pISR_SPI0       (*(unsigned *)(_ISR_STARTADDRESS+0x78))
#define pISR_UART1       (*(unsigned *)(_ISR_STARTADDRESS+0x7c))
#define pISR_NFCON       (*(unsigned *)(_ISR_STARTADDRESS+0x80))       // Added for 2440.
#define pISR_USBD       (*(unsigned *)(_ISR_STARTADDRESS+0x84))
#define pISR_USBH       (*(unsigned *)(_ISR_STARTADDRESS+0x88))
#define pISR_IIC       (*(unsigned *)(_ISR_STARTADDRESS+0x8c))
#define pISR_UART0       (*(unsigned *)(_ISR_STARTADDRESS+0x90))
#define pISR_SPI1       (*(unsigned *)(_ISR_STARTADDRESS+0x94))
#define pISR_RTC       (*(unsigned *)(_ISR_STARTADDRESS+0x98))
#define pISR_ADC       (*(unsigned *)(_ISR_STARTADDRESS+0x9c))


当程序发生中断的时候,程序指针就会跳转到相应的地址执行程序
,此地址中再存放一条跳转到中断服务程序的指令。(如果在中断服务程序里面查询SUBSRCPND中对应位的情况就可以判断中哪一个子中断源发生了中断)(个人理解,仅供参考)
这是本人写好的程序(触屏切换图片):
http://www.tudou.com/programs/view/NJjDms5QoqI/

手机版|小黑屋|51黑电子论坛|51黑电子论坛6群QQ管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网