The interrupt controller in S5PV210 is composed of four Vectored Interrupt Controller (VIC), ARM PrimeCell PL192 and four TrustZone Interrupt Controller (TZIC), SP890. 1.1 KEY FEATURES OF VECTORED INTERRUPT CONTROLLER • Supports 93 vectored IRQ interrupts • Fixed hardware interrupts priority levels • Programmable interrupt priority levels • Supports Hardware interrupt priority level masking • Programmable interrupt priority level masking • Generates IRQ and FIQ • Generates Software interrupt • Test registers • Raw interrupt status • Interrupt request status • Supports Privileged mode for restricted access 1.2 NTERRUPT SOURCE S5PV210中断源分为四组VIC0-3,每组32个中断源(有的缺省)。例如:EINT16_31属于VIC0第16位; 这里以外部中断16为例,下面对各个Register进行配置: EINT16是属于一个GPIO口---GPH2_0,我开发板上GPH2_0 是接的的一个按键,这里就以一个按键按下触发中断为例。首先当然的先配置该GPIO的工作模式进行配置: 这里肯定是选择GPH2CON |= 0xF; //1111---EXT_INT[16] 我们已经配置GPH2_0 工作在中断模式下了,接下就该配置中断的触发方式和是否屏蔽改中断了 外部中断共有四组EXT_INT0-3,其中EXT_INT[16] 就属于EXT_INT2 EXT_INT_2_CON |= 1<<1;// 010 这里选择下降沿触发 EXT_INT_2_MASK &= ~(1<<0);// 0 不屏蔽 EINT16的引脚触发条件我们配置好了,接下就该配置中断寄存器了。 在中断还没配置前需要先关闭中断,关闭中断的寄存器 只需将VICI0INTENCLEAR= 0xffffffff; //关闭所有中断。 接下来就该配置中断了,s5pv210中断分为两种:IRQ interrupt 和 FIQ interrupt,这里选择的是IRQ, 为了省事这里我将VIC0组的中断源全部配置成了IRQ,其实用哪个中断源就配置哪个才是正确滴; VIC0INTSELECT=0x0; //将中断配置成IRQ 中断当然要得有中断处理函数,处理函数的地址被存放在VICADDRESS中: 在处理函数未被定义时,可先将该寄存器清零,当然复位值就是0,为了保险嘛:VIC0ADDRESS=0x0;//清除中断处理函数的入口地址, 清除后就该定义我们的处理程序了,处理函数名随便取,我们要取的是其地址,定义好后 我们就该把其地址装载到VIC0VECTADDR中 VectorAddr0-31代表这VIC0-3组内的32个中断源的地址,地址是32位占四个字节,所以中断源地址得x4. 例如:EINT16属于VIC0组第16个,EINT16的地址为Address=0xF2000100+16x4 。 (看清楚了哦,清除处理函数地址用的是VICADDRESS寄存器,而装载却用的是VICVECTADDR寄存器,是不同的两个地址) // 保存需要处理的中断的中断处理函数的地址 void intc_setvectaddr(unsigned long intnum, void (*handler)(void)) // void(*handler)(void)---指向函数的指针 { //VIC0 if(intnum<32) { *( (volatile unsigned long *)(VIC0VECTADDR + 4*intnum) ) = (unsigned)handler; } //VIC1 else if(intnum<64) { *( (volatile unsigned long *)(VIC1VECTADDR + 4*(intnum-32)) ) = (unsigned)handler; } //VIC2 else if(intnum<96) { *( (volatile unsigned long *)(VIC2VECTADDR + 4*(intnum-64)) ) = (unsigned)handler; } //VIC3 else { *( (volatile unsigned long *)(VIC3VECTADDR + 4*(intnum-96)) ) = (unsigned)handler; } return; } 处理函数也配置好了,接下来就只剩下开启中断了 void intc_enable(unsigned long intnum) { unsigned long temp; if(intnum<32) { temp = VIC0INTENABLE; temp |= (1< VIC0INTENABLE = temp; } } 往VIC0INTENABLE 中写1即可,到这里一个EINT16就配置好了。你可以在中断服务函数中实现你想要的功能了, void isr_key(void) //中断处理函数 { printf("we get company:EINT16_31rn"); intc_clearvectaddr(); // clear VIC0ADDR EXT_INT_2_PEND |= 1<<0; // clear pending bit } int main(void) { int c = 0; uart_init();// 初始化串口 system_initexception(); // 中断相关初始化 // 外部中断相关的设置 GPH2CON |= 0xF; // 1111 = EXT_INT[16] EXT_INT_2_CON |= 1<<1; // 010 = Falling edge triggered EXT_INT_2_MASK &= ~(1<<0); // unmasked intc_setvectaddr(NUM_EINT16_31, isr_key); // 设置中断EINT16_31的处理函数 intc_enable(NUM_EINT16_31);// 使能中断EINT16_31 while (1) { printf("%drn",c++); delay(0x100000); } } |
更多回帖