以下是我自己总结的一些经验:
一。中断的跳转过程
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);
}
文章评论(0条评论)
登录后参与讨论