标签:
_start:
1、设置栈空间:防止之前的UBOOT代码被覆盖,应为c中需要栈空间
ldr sp, =0x40010000
2、设置CPSR的I,F位,A8打开IRQ,FIQ中断:
mov r0, #0x53
msr CPSR_cxsf, r0
b main
--main函数:
1、led灯引脚功能设置
GPJ2CON &= ~(0xf<<0);
GPJ2CON |= (1<<0);
2、中断初始化:
2、1 注册中断函数:
pExceptionFIQ = (unsigned long)FIQ_handle;//FIQ
pExceptionIRQ = (unsigned long)IRQ_handle;//IRQ
功能函数:
_start:
IRQ_handle: @CPSR会由硬件自动保存到SPSR_irq
ldr sp, =0xD0037F80
sub lr, lr, #4
stmfd sp!, {r0-r12, lr}
bl Irq_Isr 跳转到真正的中断处理函数 *irq= VIC0ADDRESS(存放了真正中断处理函数的首地址)
ldmfd sp!, {r0-r12, pc}^ @将SPSR_irq恢复给CPSR
中断处理函数的执行:
void Irq_Isr(void)
{
int i;
unsigned long vicaddr[4] = {VIC0ADDRESS,VIC1ADDRESS,VIC2ADDRESS,VIC3ADDRESS};
void (*isr)(void) = (void *)0;
for(i=0; i<4; i++)
{
if(intc_getvicirqstatus(i) != 0)
{
isr = (void (*)(void)) vicaddr[i];
break;
}
}
(*isr)();
}
2、2 关闭中断控制器:()
VIC0INTENCLEAR = 0xffffffff;
VIC1INTENCLEAR = 0xffffffff;
2、3 设置为何种中断(IRQ)
VIC0INTSELECT = 0x0;
VIC1INTSELECT = 0x0;
3、将真正的中断处理函数地址给对应的寄存器VIC0VECTADDR,
真正的中断处理函数:
电灯,清除VIC0VECTADDR中保存的地址,清除外部中断的标志位,PEND
void isr_key(void)
{
GPJ2DAT ^= (1<<0); //toggle
// clear VIC0ADDRESS
intc_clearvectaddr();
// clear pending bit
EXT_INT_2_PEND |= 1<<0;
}
4、设置按键功能,以及为何种触发方式
// GPH2_0 --> EXT_INT[16]
GPH2CON |= 0xF;
//EXT_INT[16]: Falling edge triggered
EXT_INT_2_CON &= ~(7<0);
EXT_INT_2_CON |= (2<<0);
5、打开外部中断
EXT_INT_2_MASK &= ~(1<<0);
6、打开中断控制器的中断功能:
void intc_enable(unsigned long intnum)
{
unsigned long temp;
if(intnum<32)
{
temp = VIC0INTENABLE;
temp |= (1<<intnum);
VIC0INTENABLE = temp;
}
}
7、进入死循环,等待中断
具体代码参考demo_irq
标签:
原文地址:http://www.cnblogs.com/defen/p/5386591.html