S3C6410裸机 - 外部中断程序

发布时间: 2024-09-20
来源: 电子工程世界

一、外部中断分组:


外部中断组0  GROUP0  GPN0--GPN15  GPL8--GPL14  GPM0--GPM4


外部中断组1  GROUP1  GPA0--GPA7   GPB0--GPB6


外部中断组2  GROUP2  GPC0--GPC7


外部中断组3  GROUP3  GPD0--GPD5


外部中断组4  GROUP4  GPF0--GPF14


外部中断组5  GROUP5  GPG0--GPG7


外部中断组6  GROUP6  GPH0--GPH9


外部中断组7  GROUP7  GPO0--GPO15


外部中断组8  GROUP8  GPP0--GPP14


外部中断组9  GROUP9  GPQ0--GPQ9


二、中断组的中断号:


NO      中断源                       说明                             GROUP


0      INT_EINT0        外部中断组0 bit[0-3]                   VIC0


1      INT_EINT1        外部中断组0 bit[4-11]                 VIC0


32    INT_EINT2        外部中断组0 bit[12-19]               VIC1


33    INT_EINT3        外部中断组0 bit[20-27]               VIC1


53    INT_EINT4        外部中断组1-9                           VIC1


三、中断程序配置:


1、设置相应的GPIO口为外部中断模式;


所用到的寄存器:GPxCON


1     //清除GPN0 GPN1

2     GPNCON &=~(3 << 0);

3     GPNCON &=~(3 << 2);

4     

5     //GPN0 GPN1设置为中断模式

6     GPNCON |= (1 << 1);

7     GPNCON |= (1 << 3);



2、配置外部中断相关的配置寄存器;

所用到的寄存器:EINT0CONx(配置中断触发方式)

EINT0MASK(失能中断屏蔽,使能中断)

PRIORITY(中断优先级配置)


1     //EINT0,1下降沿触发

2     EINT0CON0 &=~(7 << 0);

3     EINT0CON0 |= (2 << 0);

4     

5     //失能中断屏蔽

6     EINT0MASK &=~(1 << 0);

7     EINT0MASK &=~(1 << 1);


3、使能中断源请求

所用到的寄存器:VICxINTENABLE


1 /使能中断源请求

2 VIC0INTENABLE |= (1 << 0);

 

4、配置向量地址


所用到的寄存器:VIC0VECTADDRx(把中断服务函数的地址写入向量地址寄存器)


1 //配置向量地址

2 VIC0VECTADDR0 = (int)IRQ_Handle_Exit;

 


5、允许向量中断(6410支持非向量中断和向量中断。210只支持向量中断不需要做此步骤)


所用到的寄存器:协处理器CP15的C1控制寄存器(置位bit24)


6、使能IRQ中断(开总中断)


所用到的寄存器:程序状态寄存器CPSR


 1     __asm__(

 2         //允许向量中断

 3         'mrc p15, 0, r0, c1, c0, 0n'

 4         'orr r0, r0, #(1 << 24)n'

 5         'mcr p15, 0, r0, c1, c0, 0n'

 6         //开RIQ总中断

 7         'mrs r0, cpsrn'

 8         'bic r0, r0, #(1 << 7)n'

 9         'msr cpsr_c, r0n'

10         :

11         :

12     );


7、编写中断服务程序


保护现场


中断程序


清除中断标志


EINT0PEND清除中断标志(写1清零)


VICxADDRESS清除向量地址


恢复现场


 1 void IRQ_Handle_Exit(void)

 2 {

 3     //保护现场

 4     __asm__(

 5         'sub lr, lr, #4n'

 6         'stmfd sp!, {r0-r12, lr}n'

 7         :

 8         :

 9     );

10     

11     //服务程序

12     if(EINT0PEND & (1 << 0))            //EINT0

13     {

14         led_all_on();

15     }

16     else if(EINT0PEND & (1 << 1))        //EINT1

17     {

18         led_all_off();

19     }

20     

21     //清除中断标志

22     EINT0PEND = 0xFFFFFFFF;

23     VIC0ADDRESS = 0x00000000;

24     

25     //恢复现场

26     __asm__(

27         'ldmfd sp!, {r0-r12, pc}^n'

28         :

29         :

30     );

31 }


8、启动代码设置


设置IRQ堆栈


 1 //start.S

 2 init_stack:

 3     //初始化IRQ SP

 4     msr cpsr_c, #0xd2

 5     ldr sp, =0x53000000

 6 

 7     //初始化SVC SP

 8     msr cpsr_c, #0xd3

 9     ldr sp, =0x54000000

10     mov pc ,lr


文章来源于: 电子工程世界 原文链接

本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。