嵌入式学习小组
直播中

刘华湘

7年用户 252经验值
私信 关注

S5PV210中断配置详解

      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);
        }
}




更多回帖

发帖
×
20
完善资料,
赚取积分