S3C2440之中断操作(MDK4.22)
2440中断控制器接收60个中断源。
中断被分为多种类别,此处为32类别,正好用32位。
图上可以很好的表示整个中断的流程。有些中断源对应一个中断类别,比如串口中断发送,接收最后都对应到串口中断。submask屏蔽子类别,未屏蔽的会引起srcpnd相应位置位,如果mask未屏蔽的话,就会紧接着判断优先级,最后导致intpnd置位,然后产生了IRQ,而FIQ不需要优先级判断,会直接产生,由intmod设置。
注意的是:进入ISR后,清除中断的顺序很重要,首先是srcpnd接着是intpnd,如果还需要清除eintpnd的话,要最先清除。
实验过程:
编译工具--MDK4.22
硬件图
首先需要配置GPF0/1/2/4的脚为EINT0/1/2/4。
由于用到了外部4-7中断,需要开启EINTMASK寄存器相应位。设置优先级寄存器,设置INTMSK寄存器。
在2440A.s中已经设置了I F位开启,可以接收中断了。
在中断初始化代码里,需要将中断函数的地址安装到中断向量表中。
程序如下:
MDK4.22的启动代码设置
配置了堆,栈,以及中断向量表的地址为0x33ffff20处。配置了B口和F口,B口试LED的灯显示,F口是连接按键的外部中断。按一个键会亮一个LED。
int.c代码
view plain
- #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);
- }
主程序:
view plain
- #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
S3C2440中断操作MDK4 2 相关文章:
- Linux2.4内核为我们带来了什么?(11-12)
- RedHatLinux新手入门教程(11-12)
- RedHatLinux新手入门教程(2)(11-12)
- 让Windows系统也能访问Linux文件系统(04-15)
- 达芬奇数字媒体片上系统的架构和Linux启动过程(06-02)
- 基于s3c2410的CramFS根文件系统的移植(07-13)