#pragma DATA_SECTION("vectors")//将中断向量绝对定位到0x80处
uVectorEntry g_pfnVectors[] = {
ISR_Reset(), //reset 0x0080 #0//软硬件复位nISR_REST
ISR_Default(), //nmi 0x0084 #1//非屏蔽中断nISR_NMI
ISR_Default(), //sint17 0x0088 #2//软件中断17
ISR_Default(), //sint18 0x008c #3//软件中断18
ISR_Default(), //sint19 0x0090 #4//软件中断19
ISR_Default(), //sint20 0x0094 #5//软件中断20
ISR_Default(), //sint21 0x0098 #6//软件中断21
ISR_Default(), //sint22 0x009c #7//软件中断22
ISR_Default(), //sint23 0x00a0 #8//软件中断23
ISR_Default(), //sint24 0x00a4 #9//软件中断24
ISR_Default(), //sint25 0x00a8 #10//软件中断25
ISR_Default(), //sint26 0x00ac #11//软件中断26
ISR_Default(), //sint27 0x00b0 #12//软件中断27
ISR_Default(), //sint28 0x00b4 #13//软件中断28
ISR_Default(), //sint29 0x00b8 #14//软件中断29
ISR_Default(), //sint30 0x00bc #15//软件中断30
ISR(Eint0Isr), //int0 0x00c0 #16//外部中断0
ISR(Eint1Isr), //int1 0x00c4 #17//外部中断1
ISR(Eint2Isr), //int2 0x00c8 #18//外部中断2
ISR(Timer0Isr),//tint 0x00cc #19//定时器中断0
ISR(McBSPIsr), //rint0 0x00d0 #20//McBSP0接收中断
ISR_Default(), //xint0 0x00d4 #21//McBSP0发送中断
ISR_Default(), //rint1 0x00d8 #22//McBSP1接收中断
ISR(Timer1Isr),//xint1 0x00dc #23//定时器中断1
ISR(Eint3Isr), //int3 0x00e0 #24//外部中断3
ISR_Default(), //hpint 0x00e4 #25//HPI中断
ISR_Default(), // 0x00e8 #26//软件中断10
ISR_Default(), // 0x00ec #27//软件中断11
ISR_Default(), // 0x00f0 #28//软件中断12
ISR_Default(), // 0x00f4 #29//软件中断13
ISR_Default(), // 0x00f8 #30//保留0
ISR_Default(), // 0x00fc #31//保留1
};
其中宏实际是“嵌入汇编”:
#define ISR_Reset() {DSPCODE_BD, (pfnVectorEntry)c_int00, DSPCODE_SP_200L, DSPCODE_SP_200H}
#define ISR_Return() {DSPCODE_RETE, (pfnVectorEntry)DSPCODE_NOP, DSPCODE_NOP, DSPCODE_NOP}
#define ISR_Default() {DSPCODE_BD, (pfnVectorEntry)DefaultIsr, DSPCODE_NOP, DSPCODE_NOP}
#define ISR(addr) {DSPCODE_BD, (pfnVectorEntry)addr, DSPCODE_NOP, DSPCODE_NOP}
//注意:宏ISR_Load()调用前应该关闭中断,装载后再开放中断
#define ISR_Load(nISR, addr) {g_pfnVectors[nISR].Isr = (pfnVectorEntry)addr;}
//注意:宏ISR_UnLoad()调用前应该关闭中断,卸载后再开放中断
#define ISR_UnLoad(nISR) {g_pfnVectors[nISR].Isr = (pfnVectorEntry)DefaultIsr;}
这里的汇编代码用枚举来替代:
enum DspCodeEnum_Enum
{
DSPCODE_BD = (TI_IREG)0xf273u,//等效BD address指令
DSPCODE_B = (TI_IREG)0xf073u,,//等效B address指令
DSPCODE_RETE = (TI_IREG)0xf4fbu,,//等效rete指令
DSPCODE_NOP = (TI_IREG)0xf495u,//等效nop指令
DSPCODE_SP_200L = (TI_IREG)0x7718u,//STM #200,SP
DSPCODE_SP_200H = (TI_IREG)0x00c8u//STM #200,SP
};
例如ISR(Timer0Isr),它表示在19#中断向量nISR_TINT0的位置0xcc处为Timer0Isr的入口。
为了编写Timer0Isr,我们还要进行2方面的工作:
1.初始化定时器,设置100MHz时10mS中断的时间常数
void TimerObj::Timer0Init(void)
{
SREGs.TIMER0.TCR.Bits.TSS = 1;//关闭定时器0
SREGs.TIMER0.TCR.Bits.TDDR = 16 - 1;//16分频
SREGs.TIMER0.PRD = 62500 - 1;//设置定时周期(PRD->TIM)
SREGs.TIMER0.TIM = 62500 - 1;//设置定时计数器
SREGs.TIMER0.TCR.Bits.TSS = 0;//启动定时器0
SREGs.IMR.Bits.TINT0 = 1;//允许TINT0中断(62500*16=10mS)
}
2.编制定时器中断服务程序
extern "C" interrupt void Timer0Isr(void)
{//每10mS中断1次
static unsigned int Count = 0;
Count ++;
if (Count > 50)//16*62500*50=0.5S
{//Led工作灯XF半秒翻转1次,注意XF的变化不是改写ST1而是改写SP(1)
SREGs.SP.Ptr[1] ^= (1 << ST1_XF);//改写SP(1)
Count = 0;
}
SREGs.IFR.Bits.TINT0 = 1;//清除定时器0中断标志
}
疑问:extern "C" interrupt void Timer0Isr(void)
是不是可以改为: interrupt void Timer0Isr(void)?我认为是可以的