📄 irq.c
字号:
#include "irq.h"
//终端处理服务函数表
F_INTERRUPT_ISR afInterrupt[66];
/**********************************************************************
* 函数名称: IRQ_Init
* 功能描述:
* IRQ中断初始化
* 参数说明:
* 无
* 返回值
* 无
******************************************************************/
void IRQ_Init(void)
{
//IRQ中断掩码全部屏蔽
INTMSK = 0xFFFFFFFF;
INTSUBMSK = 0xFFFFFFFF;
EINTMASK = 0xFFFFFFFF;
//IRQ中断标志全部清零
SRCPND = 0xFFFFFFFF;
EINTPEND = 0xFFFFFFFF;
SUBSRCPND = 0xFFFFFFFF;
memset(afInterrupt, 0, sizeof(afInterrupt));
}
/**********************************************************************
* 函数名称: IRQ_Dispatch
* 功能描述:
* IRQ中断分发服务函数
* 在产生IRQ中断时调用次函数,并由此函数将中断分发给各个中断服务函数
* 参数说明:
* 无
* 返回值
* 无
******************************************************************/
void IRQ_Dispatch()
{
int i ;
if( (int)INTOFFSET >= 0 && (int)INTOFFSET <= 31 )
{
switch(INTOFFSET)
{
//二级外部中断
case INT_TYPE_EINT4_7:
case INT_TYPE_EINT8_23:
for(i = 4; i <= 23; i++)
{
if((EINTPEND & (1 << i)) >> i )
{
EINTPEND |= (1<<i);
//如果相应的中断服务函数已注册,则执行
if(afInterrupt[28 + i] != NULL)
{
afInterrupt[28 + i](); //处理中断
i = 3;
}
}
}break;
//二级内部中断
case INT_TYPE_INT_UART0:
case INT_TYPE_INT_UART1:
case INT_TYPE_INT_UART2:
case INT_TYPE_INT_ADC:
case INT_TYPE_INT_CAM:
case INT_TYPE_INT_WDT_AC97:
for(i = 0; i <= 14; i++)
{
if((SUBSRCPND & (1 << i)) >> i )
{
//如果相应的中断服务函数已注册,则执行
if(afInterrupt[52 + i] != NULL)
{
afInterrupt[52 + i](); //处理中断
SUBSRCPND = 1 << i;
break;
}
}
}break;
//一级中断
default:
//如果相应的中断服务函数已注册,则执行
if(afInterrupt[INTOFFSET] != NULL)
{
afInterrupt[INTOFFSET](); //处理中断
}
}
SRCPND |= 1 << INTOFFSET; //清除标志位
INTPND |= 1 << INTOFFSET; //清除标志位
}
}
/**********************************************************************
* 函数名称: IRQ_Install
* 功能描述:
* 装载中断服务函数(一级中断直接安装即可,二级中断需先通过
* IRQ_SetMask设置相关的一级中断为INT_MASK_ENABLE)
* 参数说明:
* nInterruptNo 将服务函数安装到服务函数表中对应的编号
* fInterruptISR 安装的中断服务函数
* 返回值
* 无
*****************************************************************/
void IRQ_Install(int nInterruptNo, F_INTERRUPT_ISR fInterruptISR)
{
if( (nInterruptNo >= 0 && nInterruptNo <= 66))
{
afInterrupt[nInterruptNo] = fInterruptISR;
IRQ_SetMask(nInterruptNo, INT_MASK_ENABLE);
}
}
/**********************************************************************
* 函数名称: IRQ_UnInstall
* 功能描述:
* 卸载中断服务函数
* 参数说明:
* 无
* 返回值
* 无
*****************************************************************/
void IRQ_UnInstall(int nInterruptNo)
{
if( (nInterruptNo >= 0 && nInterruptNo <= 66))
{
afInterrupt[nInterruptNo] = NULL;
IRQ_SetMask(nInterruptNo, INT_MASK_DISABLE);
}
}
/**********************************************************************
* 函数名称: IRQ_SetMask
* 功能描述:
* 设置中断掩码
* 参数说明:
* 无
* 返回值
* 无
*****************************************************************/
void IRQ_SetMask(int nInterruptNo, int nEnable)
{
//一级中断
if( (nInterruptNo >= 0 && nInterruptNo <= 31))
{
if(nEnable == INT_MASK_ENABLE)
{
//开启一级中断
INTMSK &= ~(1 << nInterruptNo);
}
else if(nEnable == INT_MASK_DISABLE)
{
//关闭一级中断
INTMSK |= 1 << nInterruptNo;
}
}
//二级外部中断
else if(nInterruptNo >= 32 && nInterruptNo <= 51)
{
//调整nInterruptNo使nInterruptNo从编号4开始
//方便和EINTMASK寄存器对应上
//因为EINTMASK是从第4位开始有效
nInterruptNo = nInterruptNo - 28;
if(nEnable == INT_MASK_ENABLE)
{
//开启二级外部中断
EINTMASK &= ~(1 << nInterruptNo);
}
else if(nEnable == INT_MASK_DISABLE)
{
//关闭二级外部中断
EINTMASK |= 1 << nInterruptNo;
}
}
//二级内部中断
else if(nInterruptNo >= 52 && nInterruptNo <= 66)
{
//调整nInterruptNo使nInterruptNo从编号0开始,方便和INTSUBMSK寄存器对应上
nInterruptNo = nInterruptNo - 52;
if(nEnable == INT_MASK_ENABLE)
{
//开启二级内部中断
INTSUBMSK &= ~(1 << nInterruptNo);
}
else if(nEnable == INT_MASK_DISABLE)
{
//关闭二级内部中断
INTSUBMSK |= 1 << nInterruptNo;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -