?? 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 + -