ARMulator下定時器中斷測試程式
阿新 • • 發佈:2019-01-30
/****************************************************************************************/ /* NAME: test.c */ /* DESC: test doby through I/O Port with timer interrupt(1s). */ /* Date: 06.18.2008 */ /* version: 0.0 */ /* Program: Shen Hui (Shh) */ /****************************************************************************************/ /* 程式主要演示怎樣使用armulator的定時器中斷.輸入也可以不在程式中賦值,直接在記憶體中改 */ /* 關鍵的地方在: */ /* 1>.要開啟中斷. */ /* 2>.要更改IRQ的服務程式. */ /* 3>.'服務程式'必須離'向量'在32MB範圍內.即25位地址. */ /* 4>.無中斷向量初始化程式(無.s檔案),只設置了IRQ. */ /* 5>.目標CPU必須與偵錯程式一致(例如,同是arm920T). */ /* 6>.MMU/PU initialization Pagetab必須設定為NO_PAGERABLES,否則對映不對 */ /****************************************************************************************/ /*Input: */ /* 0805ff01: D0-start h active */ /* 0805ff02: D0-stop l active */ /*Output: */ /* 0805ff0d: D0-doby1 l active 0805ff0e: D0-doby1 l active */ /* D1-doby1 l active D1-doby1 l active */ /* D2-doby1 l active D2-doby1 l active */ /* D3-doby1 l active D3-doby1 l active */ /* D4-doby1 l active D4-doby1 l active */ /* D5-doby1 l active D5-doby1 l active */ /* D6-doby1 l active D6-doby1 l active */ /* D7-doby1 l active D7-doby1 l active */ /****************************************************************************************/
#include "test.h"
void itoa2(unsigned short n, unsigned char *str) {//not find itoa in stdlib.h int i=0; int swap; do { str[i]=n%2+'0'; i++; }while(n/=2); str[i--]='/0'; for(n=0; n<i; n++, i--) { swap=str[n]; str[n]=str[i]; str[i]=swap; } }
void __irq IRQ_Handler(void) { unsigned status;
status = IRQStatus; /* 處理中斷源 */ if (status & IRQTimer1) { Timer1Clear = 0; /* 清除中斷 */ IntCT1++; /* 置標記 */ } }
/* ************************************************** */ /* 更新'向量'的內容使他包含一個轉移到'服務程式'的指令 */ /* 函式返回原'向量'值. */ /* 注意: '服務程式'必須離'向量'在32MB範圍內. */ /* ************************************************** */ unsigned Install_Handler (unsigned routine, unsigned *vector) { unsigned vec, oldvec; vec = ((routine - (unsigned)vector - 0x8)>>2); if (vec & 0xff000000) { printf ("Installation of Handler failed"); exit(1); } vec = 0xea000000 | vec;//EA= oldvec = *vector; *vector = vec; return (oldvec); }
/* ************************************************** */ /* 開啟或關閉中斷 */ /* 通過讀 cpsr 標記然後更新第7位來開啟或關閉中斷 */ /* 這些函式只能用於 privileged 模式,因為cpsr和spsr的 */ /* 控制位在使用者模式下不能改變. */ /* ************************************************** */ __inline void enable_IRQ(void) { int tmp; __asm { MRS tmp, CPSR BIC tmp, tmp, #0x80 MSR CPSR_c, tmp } } // __inline void disable_IRQ(void) { int tmp; __asm { MRS tmp, CPSR ORR tmp, tmp, #0x80 MSR CPSR_c, tmp } }
// 如果目標為920T則要清除所有中斷捕獲! int main(void) { unsigned short Mask=1; unsigned char *str; DOBYINPUT0_7=0xff; DOBYINPUT8_F=0xff; // itoa2(0x1234,str ); // printf("str %s/n",str); printf("Timer Interrupt/n"); //未安裝前 00000018 [0xe7ff0010] dci 0xe7ff0010 ; ? undefined //使地址(IRQ)00000018處為: [0xea002022] * b IRQ_Handler Install_Handler ((unsigned)IRQ_Handler, irqvec); printf("Normal (RAM at 0x8000, semihosting) version/n/n"); printf("Initializing.../n"); // enable_IRQ();
IRQEnableClear = ~0; // 清除所有的中斷 Timer1Control = 0; // 通過控制位關閉計數器 Timer1Clear = 0 ; // 通過寫任何值到'清除'清除暫存器來清除中斷 Timer1Load = 2000; // 裝計數器值,可通過晶頻計算,這裡2000只是為了測試
Timer1Control = (TimerEnable | TimerPeriodic | TimerPrescale8 );
IRQEnableSet = IRQTimer1;
printf("Running.../n");
IntCT1 = 0; // 清 CT1 標記 while (START) { if(STOP) break; if (IntCT1 != 0) // 定時器1產生中斷 { IntCT1 = 0; // 復位定時器1中斷標記 DOBYOUTPUT0_7 = (~Mask) & 0xFF; DOBYOUTPUT8_F =((~Mask) & 0xFF00)>>8; itoa2(Mask,str); printf("%016s/n",str); Mask<<=1; if(Mask==0) Mask=1; } } printf("Ended/n"); disable_IRQ(); }