S3C2440之中斷操作(MDK4.22)
2440中斷控制器接收60個中斷源。
本文引用地址:http://www.ex-cimer.com/article/201611/318143.htm中斷被分為多種類別,此處為32類別,正好用32位。
圖上可以很好的表示整個中斷的流程。有些中斷源對應(yīng)一個中斷類別,比如串口中斷發(fā)送,接收最后都對應(yīng)到串口中斷。submask屏蔽子類別,未屏蔽的會引起srcpnd相應(yīng)位置位,如果mask未屏蔽的話,就會緊接著判斷優(yōu)先級,最后導(dǎo)致intpnd置位,然后產(chǎn)生了IRQ,而FIQ不需要優(yōu)先級判斷,會直接產(chǎn)生,由intmod設(shè)置。
注意的是:進入ISR后,清除中斷的順序很重要,首先是srcpnd接著是intpnd,如果還需要清除eintpnd的話,要最先清除。
實驗過程:
編譯工具--MDK4.22
硬件圖
首先需要配置GPF0/1/2/4的腳為EINT0/1/2/4。
由于用到了外部4-7中斷,需要開啟EINTMASK寄存器相應(yīng)位。設(shè)置優(yōu)先級寄存器,設(shè)置INTMSK寄存器。
在2440A.s中已經(jīng)設(shè)置了I F位開啟,可以接收中斷了。
在中斷初始化代碼里,需要將中斷函數(shù)的地址安裝到中斷向量表中。
程序如下:
MDK4.22的啟動代碼設(shè)置
配置了堆,棧,以及中斷向量表的地址為0x33ffff20處。配置了B口和F口,B口試LED的燈顯示,F(xiàn)口是連接按鍵的外部中斷。按一個鍵會亮一個LED。
int.c代碼
- #include"S3C2440.h"
- #include"int.h"
- voidinit_irq(void)
- {
- pHandleEINT0=EINT0_Handle;
- pHandleEINT1=EINT1_Handle;
- pHandleEINT2=EINT2_Handle;
- pHandleEINT4_7=EINT4_7_Handle;
- rEINTMASK&=(~(1<<4));
- rPRIORITY=(rPRIORITY&(~(0x01)))|(0x01<<7);
- rINTMSK&=(~(1<<0))&(~(1<<1))&(~(1<<2))&(~(1<<4));
- }
- void__irqEINT0_Handle(void)
- {
- rSRCPND=1<<0;
- rINTPND=1<<0;
- rGPBDAT|=(0x0f<<5);
- rGPBDAT&=~(1<<8);
- }
- void__irqEINT1_Handle(void)
- {
- rSRCPND=1<<1;
- rINTPND=1<<1;
- rGPBDAT|=(0x0f<<5);
- rGPBDAT&=~(1<<5);
- }
- void__irqEINT2_Handle(void)
- {
- rSRCPND=1<<2;
- rINTPND=1<<2;
- rGPBDAT|=(0x0f<<5);
- rGPBDAT&=~(1<<7);
- }
- void__irqEINT4_7_Handle(void)
- {
- rEINTPEND=(1<<4);
- rSRCPND=1<<4;
- rINTPND=1<<4;
- rGPBDAT|=(0x0f<<5);
- rGPBDAT&=~(1<<6);
- }
主程序:
- #include"S3C2440.h"
- #include"int.h"
- intmain(void)
- {
- rGPBDAT|=(0xf<<5);
- init_irq();
- while(1);
- }
scatter文件如下:
LR_ROM1 0x00000000 0x00001000 { ; load region size_region
ER_ROM1 0x00000000 0x000001000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_RAM1 0x30000000 0x40000000 { ; RW data
.ANY (+RW +ZI)
}
ISR 0x31000000{
int.o(*)
}
HEAP 0x30000800 {
S3C2440A.o(HEAP)
}
STACK 0x30000c00{
S3C2440A.o(STACK)
}
}
驗證,可以按一個鍵亮一個鍵。
over
評論