原创 关于s3c2410中断机制,以及使用方法

2009-3-21 17:09 5553 8 8 分类: MCU/ 嵌入式
 对于arm来说中断的使用远比单片机复杂许多,单片机的中断跳转很单一,编译器帮你都做好了,但是想要在arm上正确完成中断的跳转,还是需要花点功夫的。

     以下是我自己总结的一些经验:


一。中断的跳转过程


1.开中断
2.发生中断 内核自动跳转到0x0000018,0x0000018处应该又一个b HandlerIRQ (中断向量表)
3.进入IRQ中断异常,执行b HandlerIRQ 这条指令在启动代买bootloder中定义好了
4.跳转到HandlerIRQ      HANDLER HandleIRQ   调用宏$HandlerLabel HANDLER $HandleLabel
5.宏的作用就是由HandlerIRQ(0x0000018)跳到Handleirq(二者对应又有区别,具体看详细的代码)。
6.下面语句就是把IsrIRQ 的地址装入HandleIRQ
    ldr r0,=HandleIRQ       ;This routine is needed
    ldr r1,=IsrIRQ          ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c
    str r1,[r0]
7.IsrIRQ的地址里面放的是C文件中服务程序的入口地址:pISR_IRQ = (unsigned)IrqHandler;


8.这样就实现了中断的跳转



值得注意:


1.ADS中断服务函数定义方法是
   static void __irq IrqHandler(void){}


如果是在GUN下,则不同


2.如果是在ram中调试的时候,必须预先把中断向量表预先烧录到0x0处,才能实现跳转


3.中断服务函数在ADS的定义没有不是利用编译器定义,而是手动把中断服务函数装载到中断向量表里面。


例如: pISR_WDT = (U32)__vWDTInterrupt;


这个函数__vWDTInterrupt装到pISR_WDT 后就像当__vWDTInterrupt是pISR_WDT 中断的服务函数,而不像单片机直接利用编译器定义中断服务函数。!



示例代码:




int irqcount = 0;


static void haha(int offset)
{


rSRCPND =0x00000010   ; //eint4~7产生中断请求
rEINTPEND = 0x00000020;   //eint5请求
rINTPND = rINTPND;

rSRCPND =0x00000010;
rEINTPEND = 0x00000020;   //外部中断5开
rINTPND = rINTPND;
irqcount++;         //统计中断次数
printf("irqcount = %d\n",irqcount); //给串口发送中断次数
}



static void __irq IrqHandler(void)   //判断具体是那个irq的外部中断请求
{
int offset;

offset = rINTOFFSET;          //读取对应的中断请求
haha(offset);
}


void Main(void)
{


pISR_IRQ = (unsigned)IrqHandler;



//GPIO
rGPFCON   &= ~(0x3<<10); // 001111111111,
rGPFCON   |= (0x2<<10);   // 100000000000,GPF6,7 input gpf5 eint5
/* rEXTINT0 &= ~(0x00600000);
rEXTINT0 |= 0x00200000;
*/
rEXTINT0 |= 0x00018000;   //设置触发方式
rGPFUP   = 0x0;          //上拉


rINTMOD   = 0x0;          //IRQ中断模式

rINTMSK   &= ~(0x00000010);//开eint4~8

rEINTMASK &= ~(0x00000020); //开中断eint5


    while(1);

}

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
8
关闭 站长推荐上一条 /3 下一条