回首頁   上一頁   通用輸出入控制    異常向量與外部中斷控制   計時器控制

串列埠UART控制    串列埠SPI控制    串列埠I2C控制    RTC控制控制    FLASH記憶體控制    uCOS-II系統程式

軟體中斷SWI實習  外部中斷FIQ實習  非向量IRQ實習  向量IRQ中斷實習 

/**********************軟體中斷SWI範例實習********************************
*檔名︰SWI.C
*功能︰可進入兩種不同的軟體中斷,控制LED遞加及閃爍。
*模擬:開啟GPIO視窗,單步執行,觀察專案視窗內暫存器及操作模式(Mode)
*附加:SWI_VEC.S
**************************************************************************/
#include "LPC2106.H"
/*************************************************************************
*函數名稱: SWI_Call1,軟體中斷1
*功能描述: LED遞加
*進入參數:j
***************************************************************************/
void SWI_Call1(uint8 j) __swi(8) // 軟體中斷1,含進入參數
{
IOCLR = LED4+LED3+LED2+LED1; // LED遞加
IOSET = j<<10;
}
/**************************************************************************
*函數名稱: SWI_Call2,軟體中斷2
*功能描述: LED閃爍
***************************************************************************/
void SWI_Call2(void) __swi(9) // 軟體中斷2
{
IOCLR=LED4+LED3+LED2+LED1; // LED閃爍
IOSET=LED4+LED3+LED2+LED1;
}
/**************************************************************************
*函數名稱: 主程式
*功能描述: 呼叫軟體中斷1-2
***************************************************************************/
void main(void)
{
uint8 i = 0;
IODIR=IOCLR=LED4+LED3+LED2+LED1; // 設定LED輸出0000
while(1)
{
SWI_Call1(i); // 呼叫軟體中斷1,含進入參數
SWI_Call2(); // 呼叫軟體中斷2,LED閃爍
i++; if(i>15) i=0; // i遞加,若i>15 則i=0
}
}

/**********************FIQ範例實習***********************************
*檔名︰FIQ.C
*功能︰令外部中斷EINT1(P14)腳=0,控制LED遞加。
*模擬:開啟GPIO、Vector Interrupt Controller及External Interrupts視窗,
* 單步執行觀察操作模式(Mode)及暫存器的變化。
* 然後快速執行,在EINT1(P14)腳輸入中斷信號,控制LED遞加
****************************************************************************/
#include "LPC2106.h"
uint16 i=0;
/*****************************************************************************
** 函數名稱: FIQ_Handler
** 功能描述: 快速中斷異常處理程式,按KEY1令外部中斷EINT1(P14)腳控制LED4-1遞加
*******************************************************************************/
void FIQ_Handler (void) __fiq //FIQ快速中斷異常服務程式
{
i++; if(i>15) i=0; // i遞加,若i>15 則i=0
IOCLR = LED4+LED3+LED2+LED1; // LED4-1=000
IOSET = i<<10; // 變數i由LED4-1輸出
Delay_ms(2) ;
while(EXTINT !=0 ) EXTINT=EXTINT1; // 等待EINT1腳=1,清除EXTINT1中斷旗標
Delay_ms(2) ;
}
/************************************************************************
*函數名稱: 主程式
*功能描述: 令外部中斷EINT1(P14)腳=0,控制LED遞加。
********************************************* ****************************/
void main(void)
{
PINSEL0=EINT1; // 設定接腳P14為EINT1
IOCLR=IODIR=LED4+LED3+LED2+LED1; // 定義輸出接腳為0000
VICIntSelect = IntEINT1; // 設定EINT1中斷使用FIQ
VICIntEnable = IntEINT1; // 致能EINT1中斷
EXTINT =EXTINT1; // 清除EINT1外部中斷旗標

while(1); // 空轉,等待EINT1外部中斷
}

/**********************非向量IRQ範列實習***************************
*檔名︰IRQ1.C
*功能︰按KEY1由外部中斷EINT1(P14)控制LED遞加,按KEY2由EINT2(P15)控制LED遞減。
*模擬:開啟GPIO及External Interrupts視窗,快速執行,在P14及P15腳輸入0產生中斷,令LED遞加或遞減
*********************************************************************/
#include "LPC2106.h"
int16 i=0;
/***********************************************************************
** 函數名稱: IRQ_Handler
** 功能描述: 外部中斷EINT2-1服務函數,令LED4-1遞加或遞減
************************************************************************/
void IRQ_Handler (void) __irq //IRQ異常服務程式
{
if(VICIRQStatus ==IntEINT1) {i++; if(i>15) i=0;} // 若是EINT1遞加
if(VICIRQStatus ==IntEINT2) {i--; if(i<0) i=15;} // 若是EINT2遞減

IOCLR = LED4+LED3+LED2+LED1; // LED4-1=000
IOSET = i<<10; // 變數i由LED4-1輸出
Delay_ms(4);
while(EXTINT !=0 ) EXTINT=EXTINT2+EXTINT1; /* 等待EINT2-1腳=1,清除EXTINT2-1中斷旗標 */
Delay_ms(4);
}
//****************************************************************/
void main(void)
{
PINSEL0=EINT2+EINT1; // 設定接腳P15-14為EINT2-1
IODIR=LED4+LED3+LED2+LED1; // 設定輸出接腳
VICIntSelect = 0x00000000; // 使用非向量IRQ

VICIntEnable =IntEINT2+IntEINT1; // 致能EINT2-1中斷
EXTINT = EXTINT2+EXTINT1; // 清除EINT2-1中斷旗標

IOCLR = LED4+LED3+LED2+LED1; // LED4-1=0000
IOSET = i<<10; // 變數i由LED4-1輸出
while(1); // 空轉,等待EINT2-1中斷
}

/*********************向量IRQ中斷範例實習**************************************
*檔名︰IRQ2.C
*功能︰按KEY1令EINT1(P14)輸入0時,令LED1反相。
* 按KEY2令EINT2(P15)輸入0時,令LED2反相。
* 按KEY3令EINT0(P16)輸入0時,令LED3反相。
*模擬:開啟GPIO及向量中斷控制器(Vector Interrupt Controller)視窗。然後快速執行,
* 在EINT0-2輸入0產生中斷,分別控制LED1-3反相。同時觀察暫存器的變化 。
****************************************************************************/
#include "LPC2106.h"
/************************************************************************
* 名稱︰IRQ_Eint0()
* 功能︰外部中斷EINT0服務程式,令LED3反相。
*************************************************************************/
void IRQ_Eint0(void) __irq
{ uint32 i;
i = VICIRQStatus; // 讀出VICIRQStatus的值及清除狀態旗標
i = IOSET; // 讀取當前LED3控制值
if((i & LED3)==0 )IOSET = LED3; // 控制LED3反相輸出
else IOCLR = LED3;
while(EXTINT !=0) EXTINT=EXTINT0;// 等待EINT0腳=1,清除EXTINT0中斷旗標
VICVectAddr = 0x00; // 清除非向量中斷位址
}
/****************************************************************************
* 名稱︰IRQ_Eint1()
* 功能︰外部中斷EINT1服務程式,令LED1反相。
****************************************************************************/
void IRQ_Eint1(void) __irq
{ uint32 i;
i = VICIRQStatus; // 讀出VICIRQStatus的值及清除狀態旗標
i = IOSET; // 讀取當前LED1控制值
if((i & LED1)==0) IOSET = LED1; // 控制LED1反相輸出
else IOCLR = LED1;
while(EXTINT !=0) EXTINT=EXTINT1;// 等待EINT1腳=1,清除EXTINT1中斷旗標
VICVectAddr = 0x00; // 清除非向量中斷位址
}
/***********************************************************************
* 名稱︰IRQ_Eint2()
* 功能︰外部中斷EINT2服務程式,令LED2反相。
************************************************************************/
void IRQ_Eint2(void) __irq
{ uint32 i;

i = VICIRQStatus; // 讀取VICIRQStatus的值及清除狀態旗標
i = IOSET; // 讀取當前LED2控制值
if((i & LED2)==0) IOSET = LED2; // 控制LED2反相輸出
else IOCLR = LED2;
while(EXTINT !=0) EXTINT=EXTINT2;// 等待EINT2腳=1,清除EXTINT2中斷旗標
VICVectAddr = 0x00; // 清除非向量中斷位址
}
/***********************************************************************
* 名稱︰main()
* 功能︰初始化外部中斷及接腳。
************************************************************************/
void main(void)
{
PINSEL0 = EINT2+EINT1; // 設定P15-14為EINT2-1
PINSEL1 = EINT0; // 設定P16為EINT0
IODIR=LED3+LED2+LED1; // 設定輸出腳
VICIntSelect = 0x00000000; // 設定所有為IRQ中斷

VICVectCntl0 =CntlEINT0; // EINT0為IRQ中斷源,優先等級最高
VICVectAddr0 =(int)IRQ_Eint0; // 設定EINT0中斷向量服務程式位址

VICVectCntl1 =CntlEINT1; // EINT1為IRQ中斷源,優先等級第二
VICVectAddr1 =(int)IRQ_Eint1; // 設定EINT1中斷向量服務程式位址

VICVectCntl2 =CntlEINT2; // EINT2為IRQ中斷源,優先等級第三
VICVectAddr2 =(int)IRQ_Eint2; // 設定EINT2中斷向量服務程式位址

VICIntEnable =IntEINT2+IntEINT1+IntEINT0; // 致能EINT2-0中斷
EXTINT = EXTINT0+EXTINT1+EXTINT2; // 清除外部EINT2-0中斷旗標
while(1); // 空轉,等待中斷
}