以s3c2440?ARM9核為例:
一:s3c2440 ARM處理器特性:
1、S3C2440支持60個中斷源,含子中斷源;
2、ARM9采用五級流水線方式;
3、支持外部中斷和內部中斷;
二、s3c2440 支持的寄存器:
2.1 外部中斷寄存器
24個外部中斷占用GPF0-GPF7(EINT0-EINT7),GPG0-GPG15(EINT8-EINT23)。用這些腳做中斷輸入,則必須配置引腳為中斷,并且不要上拉。具體可參考datesheet數據手冊。
寄存器:
EXTINT0-EXTINT2:分別設置EINT0—EINT7、EINT8—EINT15、EINT16—EINT23的觸發方式(高電平觸發、低電平觸發、下降沿觸發、上升沿觸發)。
EINTFLT0-EINTFLT3:控制濾波時鐘和濾波寬度。
EINTPEND:這個是中斷掛起寄存器,清除時要寫1,后面還有幾個是寫1清除。當一個外部中斷(EINT4-EINT23)發生后,那么相應的位會被置1。為什么沒有EINT0-EINT3,因為它們分別由SRCPND寄存器的后4位控制。
EINTMASK:這個簡單,是屏蔽中斷用的,也就是說位為1時,此次中斷無效。
2.2 內部中斷寄存器
內部中斷有8個寄存器。
寄存器:
SUBSRCPND:當一個中斷發生后,那么相應的位會被置1,表示一個中斷發生了。
INTSUBMSK:與上一個是一樣的,中斷屏蔽寄存器。
SRCPND:當一個中斷發生后,那么相應的位會被置1,表示一個或一類中斷發生了。
INTMSK:用來屏蔽SRCPND寄存器所標識的中斷。但只能屏蔽IRQ中斷,不能屏蔽FIQ中斷。
INTMOD:當INTMOD中某位被設置為1時,它對應的中斷被設為FIQ,CPU將進入快速中斷模式。
PRIORITY:用于設置IRQ中斷的優先級。具體使用方法可參考芯片手冊。
INTPND:中斷優先級仲裁器選出優先級最高中斷后,這個中斷在INTPND寄存器中的相應位被置1,隨后,CPU進入中斷模式處理它。同一時間內,此寄存器只有一位被置1。
INTOFFSET:用來表示INTPND寄存器中哪位被置1了,即記錄INTPND中位[x]為1的位x的值。清除INTPND、SRCPND時自動清除。
三、中斷處理流程
1、中斷控制器匯集各類外設發出的中斷信號,然后通知CPU。
2、CPU保存當前程序的運行環境,然后調用中斷服務程序(ISR),來處理中斷。
3、在ISR中通過讀取外設的相關的寄存器來識別中斷的類型,并進行相應的處理。
4、清除中斷:通過讀寫相關中斷控制寄存器和外設相關寄存器來實現。(注意消除中斷是必要的)
5、恢復被中斷程序的執行環境,繼續執行被中斷的程序。
四、代碼:
main.c
1 intmain()2 {3 ................4 //其他部分初始化
5 button_init();6 init_irq();7 while(1);8 return 0;9 }
interrupt.c
1 /*interrupt registes*/
2 #define SRCPND (volatile unsigned long *)0x4A000000
3 #define INTMOD (volatile unsigned long *)0x4A000004
4 #define INTMSK (volatile unsigned long *)0x4A000008
5 #define PRIORITY (volatile unsigned long *)0x4A00000c
6 #define INTPND (volatile unsigned long *)0x4A000010
7 #define INTOFFSET (volatile unsigned long *)0x4A000014
8 #define SUBSRCPND (volatile unsigned long *)0x4A000018
9 #define INTSUBMSK (volatile unsigned long *)0x4A00001c
10
11 #define EINTMASK (volatile unsigned long *)0x560000a4
12 #define EINTPEND (volatile unsigned long *)0x560000a8
13
14 voidinit_irq()15 {16
17 //對于EINT4,需要在EINTMASK寄存器中使能它
18 *(EINTMASK) &= ~(1<<4);19
20
21 //EINT0、EINT1、EINT2、EINT4_7使能
22 *(INTMSK) &= (~(1<<0)) & (~(1<<1)) & (~(1<<2)) & (~(1<<4));23
24 __asm__(25 /*開中斷*/
26 "mrs r0,cpsr\n"
27 "bic r0, r0, #0x80\n"
28 "msr cpsr_c, r0\n"
29 :30 :31 );32 }33
34 voidhandle_int()35 {36 /*讀取產生中斷的源*/
37 unsigned long value = *(INTOFFSET);38
39 switch(value)40 {41 case 0: //EINT0~K4
42 led_on();43 break;44
45 case 1: //EINT1~K1
46 led_off();47 break;48
49 case 2: //EINT2~K3
50 led_on();51 break;52
53 case 4: //EINT4~K2
54 led_off();55 break;56
57 default:58 break;59 }60
61 /*中斷清除*/
62 if(value == 4)63 *(EINTPEND) = (1 << 4);64 *(SRCPND) = 1 <
start.S
1 irq:
2 sub lr, lr, #4
3 stmfd sp!, {r0-r12, lr} /* 保護現場 */4 bl handle_int5 ldmfd sp!, {r0-r12, pc}^ /* 恢復現場,^表示把spsr恢復到cpsr */
五:部分代碼解釋:
sub lr, lr, #4