一、概述
S3C2440A 中的中断控制器接受来自 60 个中断源的请求。提供这些中断源的是内部外设,如 DMA 控制器、 UART、IIC 等等。
在这些中断源中,UARTn、AC97 和 EINTn 中断对于中断控制器而言是“或”关系。 当从内部外设和外部中断请求引脚收到多个中断请求时,中断控制器在仲裁步骤后请求 ARM920T 内核的 FIQ 或 IRQ。
仲裁步骤由硬件优先级逻辑决定并且写入结果到帮助用户通告是各种中断源中的哪个中断发生了的中断挂起寄存器中。
此处中断控制器中有 5 个控制寄存器:源挂起寄存器、中断模式寄存器、屏蔽寄存器、优先级寄存器和中断挂气寄存器
二、实现过程
前提:本次模拟以一个外部中断EINT8来模拟中断控制器,对应的引脚为GPG0。而NIET8又属于EINT8_23中断源,故此需要设置EINT8_23。
2.1.设置GPG0的功能为EINT8
2.2. 设置中断屏蔽寄存器的中断源可被服务
2.3.设置中继模式
设置为IRQ模式
2.4.设置EINT8的触发模式
设置为下降边沿模式 ;
EINT8属于外部中断源;
使用外部中断寄存器1,里面包括了EINT8;
2.5.设置外部中断寄存器为可被服务
2.6.处理中断
1.通过中级偏移寄存器判断那个IRQ中断源请求处理
此处只有EINT8_23
2.通过外部挂起寄存器,判断EINT8_23中有那些外部中断要被处理,分别进行不同的处理
只有EINT8
3.清除处理完的中断
1)清除外部挂起中断寄存器的ENIT8
向该位写入1清零
2)清除源挂起中的EINT8_23
向该位写入1清零
3)清除中断挂起寄存器中的EINT8_23
向该位写入1清零
三、实现代码
3.1.配置ENIT8
void eint8_init(void)
{//1.设置外部中断的引脚的功能为ENT8GPGCON &= ~(0x3 << 0);GPGCON |= (0x2 << 0);//2.关闭对enit8_23的屏蔽寄存器INTMSK &= ~(0x1 << 5);//此次模拟只有一处外部中断,故此中断处理优先级不用设置//3.设置enit8_23中断模式INTMOD &= ~(0x1 << 5);//4.设置eint8的触发方式 --- 下降沿触发EXTINT1 &= ~(0x7 << 0); EXTINT1 |= (0x2 << 0);//关闭对eint8的屏蔽寄存器EINTMASK &= ~(1 << 8);}
3.2.处理中断
//中断处理---不同的中断处理不同
void eint8_23_handle(void)
{ //此处只有EINT8_23中的EINT8if (EINTPEND & (1 << EINT8)){led_on(5); //打开LED1灯EINTPEND |= (0x1 << EINT8); //处理完后,清除EINT8 --- 写1清除}}void irq_handle(void)
{//管理中断偏移寄存器中,按顺序处理中断(此处只有EINT8_23)unsigned int irq_num = INTOFFSET;switch (irq_num){case EINT8_23: eint8_23_handle();break;default:break;}SRCPND |= (0x1 << irq_num); //清除源挂起中断源 --- 写1清除INTPND |= (0x1 << irq_num); //清除中继挂起中断源 --- 写1清除
}