//***********************************************
// 這是個timer0中斷的例子。
//timer0中斷服務中蜂鳴器響和LED亮。
//使用suppervivi的n功能選項下載到NANDFLASH中可運行原因如下(以下都是從網上找的):
//一般情況下,在ARM9偵錯工具都是下載到RAM中執行的,當然,只要沒有中斷產生程式看似能夠正常執行,
//但是一旦中斷髮生,程式必然會跑飛,原因在於程式中斷後,PC預設指向0x00-0x1C處,但是RAM的起始地址是0x30000000,
//中斷向量表預設在0x30000018處,很明顯,中斷服務程式是不能夠正常執行的,
//同時ARM核心會通過串口列印"Dummy_isr error........"資訊。解決辦法:
//(1)直接燒寫到nand第0塊(如果代碼大於4K,啟動代碼中必須要有拷貝到SDRAM功能)
//(2)改寫自己的程式,在初始化中斷之前將中斷向量表拷貝到內部SRAM.
//(3)利用MMU的重新導向功能
//在這裡採用了第3種方法。
//***********************************************
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "mmu.h"
#include "def.h"
#include "Option.h"
//-----延時函數--------
void dely(U32 tt)
{
U32 i;
for(;tt>0;tt--)
{
for(i=0;i<10000;i++)
{}
}
}
//----timer中斷服務程式----
void __irq Timer0_ISR(void)
{
static int count;
Uart_Printf("timer0中斷服務程式start/n");
count ++;
rSRCPND = rSRCPND | (0x1<<10);//定時器0 清零
rINTPND = rINTPND | (0x1<<10);//清中斷
if (count % 2 ==0)
rGPBDAT = ~0x1ee; //蜂鳴器響,LED亮
else if (count % 2 ==1)
rGPBDAT = 0x1ee; //蜂鳴器不響,LED滅
Uart_Printf("timer0中斷服務程式end/n");
}
//------中斷初始化-------
void INT_Init(void)
{
Uart_Printf("中斷初始化/n");
// 定時器0中斷使能
rINTMSK = ~(0x1<<10); //開啟定時器4中斷
rINTMOD = 0x0;
}
//-----IO口初始化--------
void GPIO_Init(void)
{
rGPBCON = 0x155555; //B0輸出,給蜂鳴器;B5~B8輸出,給LED
rGPBUP = 0x7ff;
rGPBDAT = 0x1e0; //蜂鳴器不響,LED滅
}
//-----timer4初始化--------
void Timer2_Init(void)
{
Uart_Printf("timer2初始化/n");
rTCFG0 &= 0xFFFF00;
rTCFG0 |= 0x00f9; // prescaler等於249
//{prescaler value}=0~255
rTCFG1 &= ~0x0000F;
rTCFG1 |= 0x00002; //divider等於8
//{divider value}=2,4,8,16
rTCNTB0 = 12500; //讓定時器0每隔0.5秒中斷一次
//定時器的輸出頻率 = PCLK/{prescaler value +1 } / {divider value}
//則設定定時器4的時鐘頻率為25kHz
rTCON &= ~0x00000F;
rTCON |= 0x00000B;
rTCON &= ~0x000002 ; //定時器0開始工作
pISR_TIMER0 = (U32)Timer0_ISR; //中斷向量註冊
}
void Main(void)
{
MMU_Init();
GPIO_Init();
INT_Init();
Timer2_Init();
while(1)
{
Uart_Printf("while!/n");
dely(150);
}
}