首先说一下外部中断:顾名思义,由s3c6410外部触发的中断就是外部中断,由s3c6410内部触发的是内部中断。
但是具体到咱们的板子上,到底哪些是外部中断,哪些是内部中断呢?可以这样概括,除了INT_EINT0---INT_EINT4之
外的都是内部中断。像watch dog就是内部中断,像key,wm9717触发的就是外部中断。
先说下外部中断从外设到cpu的具体流程:对理解中断很中重要!
外设------>GPIO------>VIC------>ARM1176
我们编写关于中断的程序也是这个过程:
配置外设------>配置GPIO------>配置VIC------>配置ARM协处理器等
总之一句话:
你要打造一个通路能够让中断的电平变化能顺顺利利的传送到ARM里!
下面就依照这个顺序讲一下:
(一)、GPIO及其配置
为什么会有GPIO呢?因为外设都是连到GPIO上嘀!s3c6410具有187个多功能I/O端口,其实有127个用于外部中
断。这127个引角呢,可以分为这么10个分组:
这里给大家分一下:
EINT0 GPN0--->GPN15 GPL8--->GPL14 GPM0--->GPM4
EINT1 GPA0--->GPA7 GPB0--->GPB6
EINT2 GPC0--->GPC7
EINT3 GPD0--->GPD5
EINT4 GPF0--->GPF14
EINT5 GPG0--->GPG7
EINT6 GPH0--->GPH9
EINT7 GPO0--->GPO15
EINT8 GPP0--->GPP14
EINT9 GPQ0--->GPQ9
每个引脚可以对应一个外部中断。
那么当外部中断电平变化传GPIO里,除了对应端口的哪几个寄存器(CON,PUD,etc)GPIO里又有哪些寄存器会
对这个中断信号造成影响呢?看下面:
EINTXCON :配置触发方式,低电平,高电平,上升沿,下降沿。
EINTXPEND :这个现在用不到,一会儿中断处理程序会用到,这个是pending register。
EINTXMASK :这里可以屏蔽某个外部中断,要通过需要clear一下对应的中断位。默认是全屏蔽的, 需要注意!
EINTXFLTCON : 这里设置滤波方式,可以去毛刺。
我们这里要设置的是EINTXCON,EINTXMASK,EINTXFLTCON。
这样我们的中断信号就可以顺利通过GPIO了,又要到哪里去呢?当时是VIC 向量中断控制器 !
(到达VIC)
上面说的这些外部中断在GPIO里分成了九组,但是具体反应到VIC里他们占用哪些中断号呢?这里贴一下:
NO SOURCES Description Group
0 INT_EINT0 External interrupt 0 ~ 3 VIC0
1 INT_EINT1 External interrupt 4 ~ 11 VIC0
32 INT_EINT2 External interrupt 12 ~ 19 VIC1
33 INT_EINT3 External interrupt 20 ~ 27 VIC1
53 INT_EINT4 External interrupt Group 1 ~ Group 9 VIC1
(前四个中断号 覆盖了EINT0,他们共用这四个中断号。53中断号覆盖了1--->9组中断引角,他们悲剧的共用一个中断号)
这里我们使用VIC,当然要先开启VIC,这个是在协处理器里设置的 VE位
- // enable VE
- __asm__ __volatile__(
- "mrc p15,0,r0,c1,c0,0/n"
- "orr r0,r0,#(1<<24)/n"
- "mcr p15,0,r0,c1,c0,0/n"
- :
- :
- :"r0"
- );
这样我们的VIC就能用了。
这里就简单了,就这么几个重要的寄存器
VICXINTSELECT 选择中断方式FIQ or IRQ。
VICXVECTADDR 设置中断处理程序的地址。
VICXINTENABLE 使能GPIO传过来的中断信号。
其实设置到这里外部中断就能正确运行了,但是还有许多别的寄存器,比如设置什么优先级的,大家如果需要就添上去。
(到达ARM)
ARM得知来了个中断,就和VIC进行一系列的握手,得到VICADDRESS,就开始执行我们的中断处理程序了。
另一个重要的内容,就是中断处理程序里清除中断。
我们要clear 一下EINTXPEND,clear 一下VICXADDRESS。有的人说要清除一下VICXIRQSTATUS,但是我发现我清除和不
清除没什么区别,也许是我理解的不透,哪位高手看到了,麻烦告诉我一声,谢了!也许有人要闻,EINTXPEND和VICXADDRESS
清除的顺序,我要说:无所谓了。因为在ARM发出VICIRQACK或者读VICADDRESS的时候,硬件自动屏蔽当前中断和比当前中断优先级
小的中断!但是不屏蔽更高优先级的中断。所以谁先谁后无所谓了,总之都清了就行了。
ARM把我们的中断处理程序执行后,这个循环就完了,我们的设置的就起了作用了。
下面我贴下OK6410 key中断的代码。
- // VIC
- #define VIC0INTENABLE (*(unsigned long volatile *)0x71200010)
- #define VIC0INTSELECT (*(unsigned long volatile *)0x7120000C)
- #define VIC0VECTADDR (*(unsigned long volatile *)0x71200100)
- #define VIC0IRQSTATUS (*(unsigned long volatile *)0x71200000)
- #define VIC0ADDRESS (*(unsigned long volatile *)0x71200F00)
- #define VIC0SOFTINT (*(unsigned long volatile *)0x71200018)
- #define VIC1ADDRESS (*(unsigned long volatile *)0x71300F00)
- #define VIC0INTENCLEAR (*(unsigned long volatile *)0x71200014)
- // extern interrupt
- #define EINT0CON0 (*(unsigned long volatile *)0x7F008900)
- #define EINT0MASK (*(unsigned long volatile *)0x7F008920)
- #define EINT0PEND (*(unsigned long volatile *)0x7F008924)
- #define EINT0FLTCON0 (*(unsigned long volatile *)0x7F008910)
- // GPN
- #define GPNCON (*(unsigned long volatile *)0x7F008830)
- #define GPNDAT (*(unsigned long volatile *)0x7F008834)
- #define GPNPUD (*(unsigned long volatile *)0x7F008838)
- int count =0;
- void (*show)(char *,...) = (void *)0xc7e11650;
- extern unsigned long print;
- int main()
- {
- /* enable VE (VIC ENABLE) */
- __asm__ __volatile__(
- "mrc p15,0,r0,c1,c0,0/n"
- "orr r0,r0,#(1<<24)/n"
- "mcr p15,0,r0,c1,c0,0/n"
- :
- :
- : "r0"
- );
- /* GPIO stuff */
- GPNCON &= 1<<2;
- GPNCON |= 0x2; // set GPNCON (0-1) to extern interrupt.
- GPNPUD &= ~(1<<2); // disable pull down/up.
- EINT0CON0 &= 1<< 3;
- EINT0CON0 |= 0x3; // set signal both edge trigger.
- // EINT0FLTCON0 |= (0x1 << 7);
- EINT0MASK &= ~(0x1); // clear the interrupt mask.
- /* VIC stuff */
- VIC0VECTADDR = &print;
- VIC0INTSELECT &= ~(1<<0);
- VIC0INTENABLE |= 1<<0;
- return 0;
- }
- void __do_irq(void)
- {
- show("hello extern interrupt./n");
- VIC0IRQSTATUS &= ~(1<<1);
- EINT0PEND = 1;
- VIC0ADDRESS = 0;
- VIC1ADDRESS = 0; // just in case.
- }
这里解释一下,我为什么要把滤波设置去掉呢,因为我设置延时滤波,效果不大,数字滤波也没仔细找合适的宽度,这里就是让大家理解一下外部中断
到底怎么一步步的执行的。更细节的东西,你可以在ARM1176的datasheet和向量中断控制器PL192的datasheet里找。
好了,就写到这里了,我想可以大家应该可以明白,如果明白了就在下面顶一下,如果不明白的或者错误的就在下面说下。谢谢!
另外感谢↘` 莫、離的提醒。
汇编跳转的代码
- .global print
- .extern __do_irq
- print:
- mov sp,#0x52000000
- sub lr,lr,#4
- stmfd sp!,{r0-r14}
- bl __do_irq;
- ldmfd sp,{r0-r13,pc}^
这是两个文件,汇编的主要用于模式跳转,设置irq模式下的栈地址。
上一篇:深入理解ARM体系架构(S3C6410)---arm7,arm9,arm11区别
下一篇:ARM11---中断---向量中断控制器(VIC)---结合s3c6410
推荐阅读最新更新时间:2024-03-16 14:58
- 热门资源推荐
- 热门放大器推荐
- Intelligent program synthesis framework and key scientific problems for embedded software
- 手把手教你学DSP基于TMS320F28335 第2版 (涨卿杰)
- Microelectronic Circuits Analysis and Design 2th edition_Muhammad.H..Rashid_Cengage 2011
- 轻松玩转STM32Cube(第2版) (杨百军)
- 硬件架构艺术:数字电路的设计方法与技术
- 东芝1200V SIC SBD “TRSxxx120Hx系列” 助力工业电源设备高效
- 信号数字处理的数学原理
- 电磁学