S3C6410裸机 - 外部中断程序

时间:2021-04-21 12:20:35

一、外部中断分组:

外部中断组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, 0\n"
 4         "orr r0, r0, #(1 << 24)\n"
 5         "mcr p15, 0, r0, c1, c0, 0\n"
 6         //开RIQ总中断
 7         "mrs r0, cpsr\n"
 8         "bic r0, r0, #(1 << 7)\n"
 9         "msr cpsr_c, r0\n"
10         :
11         :
12     );

 

7、编写中断服务程序

保护现场

中断程序

清除中断标志

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

                   VICxADDRESS清除向量地址

恢复现场

 1 void IRQ_Handle_Exit(void)
 2 {
 3     //保护现场
 4     __asm__(
 5         "sub lr, lr, #4\n"
 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