一直使用Freescale的S9S12G128系列,對其中斷部分有一些疑惑,想提出請大牛指點指點,話不多說直接上代碼,大家可以看3段代碼,分別是PE生成的Vector.c檔案,里面存盤了中斷向量表,另外一個是SM1.c檔案(SPI總線),其中有一個SM1_RecvChar()接收函式,與一個ISR(SM1_Interrupt)中斷函式,如下:
Vector.c檔案:
typedef void (*near tIsrFunc)(void);
/*lint -save -e950 Disable MISRA rule (1.1) checking. */
static const tIsrFunc _InterruptVectorTable[] @0x7F80U = { /* Interrupt vector table */
/*lint -restore Enable MISRA rule (1.1) checking. */
/* ISR name No. Address Name Description */
&Cpu_Interrupt, /* 0x40 0xFF80 ivVsi unused by PE */
&Cpu__ivVportad, /* 0x41 0xFF82 ivVportad used by PE */
&Cpu_Interrupt, /* 0x42 0xFF84 ivVatdcompare unused by PE */
&Cpu_Interrupt, /* 0x43 0xFF86 ivVReserved60 unused by PE */
&TI2_Interrupt, /* 0x44 0xFF88 ivVapi used by PE */
&Cpu_Interrupt, /* 0x45 0xFF8A ivVlvi unused by PE */
&Cpu_Interrupt, /* 0x46 0xFF8C ivVReserved57 unused by PE */
&Cpu_Interrupt, /* 0x47 0xFF8E ivVportp unused by PE */
&Cpu_Interrupt, /* 0x48 0xFF90 ivVReserved55 unused by PE */
&Cpu_Interrupt, /* 0x49 0xFF92 ivVReserved54 unused by PE */
&Cpu_Interrupt, /* 0x4A 0xFF94 ivVReserved53 unused by PE */
&Cpu_Interrupt, /* 0x4B 0xFF96 ivVReserved52 unused by PE */
&Cpu_Interrupt, /* 0x4C 0xFF98 ivVReserved51 unused by PE */
&Cpu_Interrupt, /* 0x4D 0xFF9A ivVReserved50 unused by PE */
&Cpu_Interrupt, /* 0x4E 0xFF9C ivVReserved49 unused by PE */
&Cpu_Interrupt, /* 0x4F 0xFF9E ivVReserved48 unused by PE */
&Cpu_Interrupt, /* 0x50 0xFFA0 ivVReserved47 unused by PE */
&Cpu_Interrupt, /* 0x51 0xFFA2 ivVReserved46 unused by PE */
&Cpu_Interrupt, /* 0x52 0xFFA4 ivVReserved45 unused by PE */
&Cpu_Interrupt, /* 0x53 0xFFA6 ivVReserved44 unused by PE */
&Cpu_Interrupt, /* 0x54 0xFFA8 ivVReserved43 unused by PE */
&Cpu_Interrupt, /* 0x55 0xFFAA ivVReserved42 unused by PE */
&Cpu_Interrupt, /* 0x56 0xFFAC ivVReserved41 unused by PE */
&Cpu_Interrupt, /* 0x57 0xFFAE ivVReserved40 unused by PE */
&CanTxInterrupt_0, /* 0x58 0xFFB0 ivVcantx unused by PE */
&CanRxInterrupt_0, /* 0x59 0xFFB2 ivVcanrx unused by PE */
&CanErrorInterrupt_0, /* 0x5A 0xFFB4 ivVcanerr unused by PE */
&CanWakeUpInterrupt_0, /* 0x5B 0xFFB6 ivVcanwkup unused by PE */
&Cpu_Interrupt, /* 0x5C 0xFFB8 ivVflash unused by PE */
&Cpu_Interrupt, /* 0x5D 0xFFBA ivVflashfd unused by PE */
&Cpu_Interrupt, /* 0x5E 0xFFBC ivVspi2 unused by PE */
&SM1_Interrupt, /* 0x5F 0xFFBE ivVspi1 used by PE */
&Cpu_Interrupt, /* 0x60 0xFFC0 ivVReserved31 unused by PE */
&AM1_Interrupt, /* 0x61 0xFFC2 ivVsci2 used by PE */
&Cpu_Interrupt, /* 0x62 0xFFC4 ivVReserved29 unused by PE */
&Cpu_Interrupt, /* 0x63 0xFFC6 ivVcpmuplllck unused by PE */
&Cpu_Interrupt, /* 0x64 0xFFC8 ivVcpmuocsns unused by PE */
&Cpu_Interrupt, /* 0x65 0xFFCA ivVReserved26 unused by PE */
&Cpu_Interrupt, /* 0x66 0xFFCC ivVReserved25 unused by PE */
&S12_LIGHT_Interrupt, /* 0x67 0xFFCE ivVportj used by PE */
&Cpu_Interrupt, /* 0x68 0xFFD0 ivVReserved23 unused by PE */
&AD1_Interrupt, /* 0x69 0xFFD2 ivVatd used by PE */
&Cpu_Interrupt, /* 0x6A 0xFFD4 ivVsci1 unused by PE */
&Cpu_Interrupt, /* 0x6B 0xFFD6 ivVsci0 unused by PE */
&Cpu_Interrupt, /* 0x6C 0xFFD8 ivVspi0 unused by PE */
&Cpu_Interrupt, /* 0x6D 0xFFDA ivVtimpaie unused by PE */
&Cpu_Interrupt, /* 0x6E 0xFFDC ivVtimpaaovf unused by PE */
&Cpu_Interrupt, /* 0x6F 0xFFDE ivVtimovf unused by PE */
&RF_SIGNAL_Interrupt, /* 0x70 0xFFE0 ivVtimch7 used by PE */
&Cpu_Interrupt, /* 0x71 0xFFE2 ivVtimch6 unused by PE */
&Cpu_Interrupt, /* 0x72 0xFFE4 ivVtimch5 unused by PE */
&Cpu_Interrupt, /* 0x73 0xFFE6 ivVtimch4 unused by PE */
&Cpu_Interrupt, /* 0x74 0xFFE8 ivVtimch3 unused by PE */
&TI3_Interrupt, /* 0x75 0xFFEA ivVtimch2 used by PE */
&TI1_Interrupt, /* 0x76 0xFFEC ivVtimch1 used by PE */
&LIN_TIMER_Interrupt, /* 0x77 0xFFEE ivVtimch0 used by PE */
&Cpu_Interrupt, /* 0x78 0xFFF0 ivVrti unused by PE */
&Cpu_Interrupt, /* 0x79 0xFFF2 ivVirq unused by PE */
&Cpu_Interrupt, /* 0x7A 0xFFF4 ivVxirq unused by PE */
&_EntryPoint, /* 0x7B 0xFFF6 ivVswi unused by PE */
&Cpu_Interrupt /* 0x7C 0xFFF8 ivVtrap unused by PE */
};
SM1.c檔案:
ISR(SM1_Interrupt)
{
SM1_TComData Data = 0U; /* Temporary variable for data */
byte Flags = 0U; /* Temporary variable for flags */
byte Status; /* Temporary variable for flags */
Status = SPI1SR; /* Read the device error register */
Data = SPI1DR; /* Read data from receiver */
Flags |= ON_RX_CHAR_EXT; /* Set the OnRxCharExt flag */
if (SerFlag & CHAR_IN_RX) { /* Is the overrun error flag set? */
SerFlag |= OVERRUN_ERR; /* If yes then set the OnError flag */
ErrFlag |= OVERRUN_ERR; /* Set the error flag for the GetError method */
Flags |= ON_ERROR; /* Set the OnError flag */
}
SerFlag |= CHAR_IN_RX; /* Set flag "char in RX buffer" */
BufferRead = Data; /* Read data from receiver */
SerFlag &= (byte)(~(byte)FULL_TX); /* Reset flag "full TX buffer" */
__DI(); /* Disable maskable interrupts */
SM1_OnRxCharExt(Data); /* If yes then invoke user event */
if(Flags & ON_ERROR) { /* Is any error flag set? */
__DI(); /* Disable maskable interrupts */
SM1_OnError(); /* If yes then invoke user event */
}
__DI(); /* Disable maskable interrupts */
SM1_OnTxChar(); /* If yes then invoke user event */
}
byte SM1_RecvChar(SM1_TComData *Chr)
{
byte FlagTmp;
if ((SerFlag & CHAR_IN_RX) == 0U) { /* Is any char in RX buffer? */
return ERR_RXEMPTY; /* If no then error */
}
EnterCritical(); /* Enter the critical section */
*Chr = BufferRead; /* Read the char */
FlagTmp = SerFlag; /* Safe the flags */
SerFlag &= (byte)(~(byte)(OVERRUN_ERR | CHAR_IN_RX | FULL_RX)); /* Clear flag "char in RX buffer" */
ExitCritical(); /* Exit the critical section */
if ((FlagTmp & OVERRUN_ERR) != 0U) { /* Is the overrun occured? */
return ERR_OVERRUN; /* If yes then return error */
} else {
return ERR_OK;
}
}
如上所示,以SPI接收資料為例,談一下個人的理解與疑惑,接收SPI總線上的資料是在中斷中處理完成的,那么當中斷產生時,應該與第一段代碼中的中斷向量表存在關系,也就是Vector.c檔案中我標紅的那一行,&SM1_Interrupt與此中斷向量有關,因此獲取到該中斷向量后與第二段代碼,ISR(SM1_Interrupt)又存在關系,此函式中將暫存器SPI1DR的值存給了一個Data 變數,緊接著Data 又賦值給了BufferRead ,而在第三段代碼中的SM1_RecvChar(SM1_TComData *Chr)函式中的指標形參*Char又被BufferRead賦值,因此工程師在呼叫SM1_RecvChar(SM1_TComData *Chr)函式時,只需定義一個與函式形參*Char型別匹配的指標傳址即可獲得到暫存器SPI1DR的值(即SPI總線資料),那么我的 疑問是:
1:當中斷SPI中斷產生時,是如何找到Vector.c檔案中這個中斷向量表的,又是如何找到&SM1_Interrupt中斷向量的?
2:當找到&SM1_Interrupt中斷向量后,程式如何運行到SM1.c中的ISR(SM1_Interrupt)函式中?
3:ISR代表中斷,而該欄位在工程中是關鍵字嗎?
uj5u.com熱心網友回復:
1. 硬體決定的和軟體沒關系。 觸發后SP自動被硬體轉到中斷向量處(如果中斷開的話)
2. 這個就和軟體有點關系了,一般的bsp包,都會在中斷向量的位置添加中斷處理函式的,你在代碼里找,應該能找到的
3. 不知道你的IDE是什么,一般都會有些關鍵字的,會用不一樣的顏色或者字體標記出來,比如像KEIL C51下中斷關鍵字是interrupt 你這個環境下就不知道了
中斷流程其實和51單片機一樣,就是有些多些可以多層嵌套
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/248750.html
標籤:單片機/工控
