1.引言 數字信號控制器(Digital Signal Controller, DSC)是將DSP內核與MCU接口相結合的微處理芯片。DSC同時具有數字信號處理能力和MCU控制接口,并且中斷系統功能非常豐富。中斷是指CPU正在處理某件事情時,突然發生的某一外部事件(如一個電平的變化,一個脈沖沿的發生或定時器的計數溢出等)請求CPU迅速去處理,此時,若條件允許,CPU暫時中斷當前的工作,轉去處理所發生的事件(中斷服務程序),處理完后,再回到原來中斷的地方,繼續原來的工作,這樣一個完整的過程稱為中斷。外設在需要時通過中斷,中止CPU當前的工作,進行信息交換;這樣可以實現CPU和多個外設同時工作,提高系統的吞吐率和使用效率。因此,中斷具有處理突發事件、提高CPU的效率、可以實現多任務數據事件管理等特點。 當多個中斷源發出中斷請求時,CPU需要選擇接收哪一個中斷源,這就帶來中斷源選擇問題。解決這個問題的方法有屏蔽選擇法、優先級選擇法和優先屏蔽選擇法三種。屏蔽選擇法主要是通過屏蔽手段將某些中斷源請求與CPU隔離;這種屏蔽中斷方法可以屏蔽系統所有中斷,也可以只屏蔽某個模塊中斷。屏蔽系統所有中斷意味著系統所有中斷請求CPU都不接受,屏蔽某個模塊中斷說明只是屏蔽的模塊中斷請求CPU不接受,其它沒屏蔽模塊中斷請求可以進入CPU。傳統51芯片采用這種方法,飛思卡爾的MC9S08AW60也采用該種方法。屏蔽選擇法通過屏蔽手段,有效地解決某些中斷源的干擾問題。 優先級選擇法通過對中斷源設置不同的優先級,當多個中斷源發出請求時,優先級高的中斷請求率先進入CPU,該中斷處理完成后,次優先級的中斷源進入CPU,以此類推。這種方法有效避免了屏蔽選擇法造成的被屏蔽中斷永遠不能被處理的不足。 優先屏蔽選擇法同時具有上述兩種方法的功能,即可屏蔽所有中斷源,也可屏蔽某些模塊中斷源,也可以對非屏蔽的中斷源進行優先級設置。這個優先級級別有多種,而51芯片優先級只有兩種(高優先級或低優先級)。這種方法即能避免優先級選擇法不能解決某些中斷源的干擾問題的缺點,又能有效避免了屏蔽選擇法造成的被屏蔽中斷永遠不能被處理的缺點。該種方法目前逐步被DSC芯片商采用,如MC56F8257芯片就采用這種方法。 從上面分析看出,DSC對中斷處理比51芯片要復雜,但從另外角度看,DSC中斷帶來更大的靈活性。靈活性與穩定性一對矛盾,本文以MC56F8257為例,從分析DSC中斷系統及其中斷處理技術入手,闡述其中斷處理方法,并給出處理步驟,為其應用提供指導。 2.MC56F8257中斷系統 MC56F8257共有67個中斷源,5個中斷優先級。中斷的請求是通過中斷控制器模塊控制的。中斷控制器模塊由中斷源、優先級設置和控制部分組成,其框圖如圖1所示,主要用于配置中斷優先級、解析中斷請求并且將中斷向量交給CPU執行。從圖1看出,在中斷請求處理過程中,當有多個中斷源發出請求(INT1…INTn)時,首先優先級別譯碼模塊根據用戶設置的優先級進行譯碼,譯碼后進入相應的優先級編碼器進行編碼,最后通過控制模塊進行優先級的配置。控制模塊根據DSP56800E核中的狀態寄存器SR中的屏蔽等設置位,對編碼后的中斷源進行處理,處理后的結果反映在控制寄存器INTC_CTRL中的INT、IPIC和VAB位。 圖1 中斷控制器框圖 INT是中斷位,該位反映內核中斷的狀態。當該位值為1時,有中斷送入內核;否則,無中斷送入內核。IPIC是中斷優先級位,該位表示送入內核的中斷源的優先級,也表示當前內核所接收的中斷的最高優先級。VAB是中斷矢量號,也是對應中斷在中斷矢量表中的地址的[7:1]位[9]。 MC56F8257內核為16位增強型DSP56800E,該內核處理中斷請求有兩種模式:標準和快速中斷處理。MC56F8257標準中斷處理模式具體流程如圖2所示,從圖2看出該模式通過JSR指令,轉向中斷服務程序,占用一定數量的軟件開銷,但所有級別中斷都支持該模式;快速中斷處理不需要執行JSR指令(如圖3),而是通過快速中斷向量地址寄存器獲得中斷服務程序首地址,節省了軟件資源,但它只能用于中斷優先級為2級的中斷。具體采用何種模式,應根據實際應用需要進行設置。 圖2 一般中斷處理的控制流程圖 圖3 快速中斷處理的控制流程圖 3.MC56F8257中斷設置方法 3.1 中斷的關閉與開放 開放MC56F8257中某個模塊中斷,通常需要開放總中斷及模塊中斷來實現。這兩部分缺一不可,并且開放總中斷在前,開放模塊中斷在后。同理,關閉MC56F8257中某個模塊中斷,需要關閉總中斷及模塊中斷來實現,先關閉模塊中斷,再關閉總中斷;如果允許中斷嵌套情況,不需關閉總中斷。 開放MC56F8257總中斷,通過清中斷控制寄存器(INTC_CTRL)的INT_DIS位;關閉總中斷,需置該位即可,具體代碼如下: #define EnableInterrupt() INTC_CTRL&=~INTC_CTRL_INT_DIS_MASK #define DisableInterrupt() INTC_CTRL|=INTC_CTRL_INT_DIS_MASK 開放或關閉模塊中斷,需設置模塊內部的控制寄存器的相應位。如開放QSCI模塊的接收中斷0,需置位QSCI控制寄存器1(QSCIx_CTRL1)中的RFIE位;關閉該中斷,清RFIE位即可,具體代碼如下: #define EnableQSCIReInt(0) QSCI_C1(0)|=(QSCI1_CTRL1_RFIE_MASK) #define DisableQSCIReInt(0) QSCI_C1(0)&=~(QSCI1_CTRL1_RFIE_MASK) 3.2 中斷優先級的設置 DSP56800E內核支持5級中斷:LP、0、1、2和3,其優先級別依次升高。最低優先級LP只能由系統SWILP指令產生;0~2優先級用戶可以編程設置,主要用于外設和外部中斷請求;級別3是最高優先級且不可屏蔽。 具體設置某個中斷源的中斷優先級,可通過設置中斷優先級寄存器(INTC_IPR0~INTC_IPR7)中的相應位。如設置QSCI中斷優先級,通過設置中斷優先級寄存器(INTC_IPR2)中的QSCI0_RCV位實現,該位具體含義見表1所示。 從表1看出,QSCI中斷可配置三個不同級別,即優先級0、1和2。如果用戶不配置QSCI中斷的優先級,系統復位時,自動分配其優先級為0;但是復位后,緊接著初始化QSCI模塊,其優先級由0級變為2級。 3.3 設置中斷屏蔽 通過設置DSP56800E內核中的狀態寄存器SR的I0、I1位,實現屏蔽不同級別優先級中斷,具體設置如表2所示。 屏蔽某個優先級中斷,可通過使能中斷優先級相應的優先級中斷來實現。例如,屏蔽優先級0中斷,可通過使能優先級1,2,3中斷實現,具體代碼如下: #define EnInt(1) {asm(bfset #0x0100,SR); asm(bfclr #0x0200,SR);} 另外,也可以同時屏蔽2個以上級別中斷,如屏蔽優先級0,1,2中斷,通過使能優先級3中斷實現,具體代碼如下: #define EnInt(3) {asm(bfset #0x0300,SR);} 在設置中斷屏蔽時,應注意的是主函數的屏蔽中斷優先級代碼與中斷服務程序的相應代碼應保證所需的中斷不被屏蔽。 3.4 中斷矢量表的定義 MC56F8257的67個中斷源,其矢量號從0到66 [9]。每個中斷源的中斷服務程序首地址放入中斷矢量表中。當有中斷請求時,CPU通過中斷矢量號在中斷矢量表中找到其中斷服務程序的首地址,根據這個首地址找到中斷服務程序,進行中斷處理。 中斷矢量表在FLSAH中的位置由向量基地址寄存器(VBA)決定。向量基地址寄存器VBA[12:0]為21位中斷矢量表首地址的高13位,低8位自動補0。具體到某個模塊中斷服務程序首地址在中斷矢量表中的位置,由向量基地址寄存器(VBA)及控制寄存器(INTC_CTRL)的VAB位決定;向量基地址寄存器VBA[12:0]為其在中斷矢量表地址[20:0]的高13位[20:8],控制寄存器(INTC_CTRL)的VAB位為其地址的[7:1],低位補0。 系統復位后,VBA的復位值為0x0000,系統進入復位中斷(矢量號為0),相應的起始地址在0x00 0000處,這個過程系統自動完成。如果開放某個模塊中斷,需要將該模塊中斷服務程序的首地址加載到中斷矢量表中的相應位置。具體過程如下:首先建立中斷矢量表;沒有開放的模塊中斷,在表中對應位置放入空函數的首地址(通過JSR isrDummy實現);開放的模塊中斷,在表中對應位置放入中斷服務程序的首地址,通常中斷服務程序由函數實現,在這里通過放入具體函數首地址實現,如開放QSCI0的接收中斷(矢量號為32),其中斷服務函數為isrSCI0_Recv,即可通過在矢量表中加入JSR isrSCI0_Recv代碼實現,具體如下: volatile asm void _vect(void); #pragma define_section interrupt_vectors "interrupt_vectors.text" RX #pragma section interrupt_vectors begin volatile asm void _vect(void) { JSR init_MC56F824x_5x_ISR_HW_RESET /* Interrupt no. 0 (Used) - ivINT_Reset */ JSR isrDummy /* Interrupt no. 1 (Used) - ivINT_COPReset */ JSR isrDummy /* Interrupt no. 2 (Unused) - ivINT_Illegal_Instruction */ . . . JSR isrSCI0_Recv /* Interrupt no. 32 (Used) - ivINT_QSCI0_RxFull */ . . . JSR isrDummy /* Interrupt no. 65 (Unused) - ivINT_GPIO_A */ JSR isrDummy /* Interrupt no. 66 (Unused) - ivINT_LP */ } #pragma section interrupt_vectors end 其中, isrDummy的函數形式如下: void isrDummy(void) { } 該函數首地址用來充當未開放模塊中斷的中斷服務程序的首地址,加載到中斷矢量表中。 4.MC56F8257中斷設置過程 MC56F8257中斷設置主要包括關閉總中斷、設置中斷屏蔽和開放總中斷三個過程。中斷的設置過程在主函數和中斷服務程序中都得體現,但二者中設置過程有所差異。 主函數中的中斷設置過程除了包括上述三個過程外,還包括開放模塊中斷及設置中斷優先級,具體流程如下:一是關閉總中斷,目的是實現后續各個模塊中斷設置過程中不被外界干擾;二是開放模塊中斷,如果需要某個模塊中斷,可以使能該模塊中斷;三是設置各模塊中斷優先級,主要應用于多個中斷請求的情況。在這種情況下,根據應用環境決定各個模塊中斷優先順序,設置中斷優先級。如果不設置優先級,系統會自動產生默認的優先級;四是設置中斷屏蔽,通過屏蔽一定級別的中斷,使系統避免受其干擾;五開放總中斷,在上述設置步驟完成后,通過開放總中斷,使其設置有效。 中斷服務程序中的中斷設置包括關閉總中斷、設置中斷屏蔽和開放總中斷三個過程。關閉總中斷和開放總中斷過程同主函數,設置中斷屏蔽過程與主函數類似,但需要注意的是主函數與中斷服務程序中的中斷屏蔽設置中應保證所需的中斷不被屏蔽。 5.測試及其分析 5.1 測試條件與環境 現以MC56F8257中的QSCI模塊中斷及CAN模塊中斷為例,說明上述中斷設置方法及實施過程,并對其過程進行分析。選用QSCI模塊的QSCI0傳輸數據,波特率設為9600。CAN模塊接收數據,CAN通信頻率為800KHz。程序編譯調試環境為CodeWarrior 10.4。測試環境為串口調試工具SSCOM V2.0。 5.2 測試結果與分析 從不帶中斷優先級、帶中斷優先級和優先級嵌套三個方面,測試分析MC56F8257中斷設置及實施過程。 (1)不帶中斷優先級 開放QSCI0接收中斷,不設置其中斷優先級,采用系統默認優先級2,不屏蔽該級別中斷,其主函數和中斷服務程序中的中斷代碼如表3所示。 從表3看出,代碼DisableInterrupt()在主函數和中斷服務程序中都有,但作用不一樣。在主函數中的作用是禁止所有中斷,為后續中斷設置提供良好環境;中斷服務程序中的作用是禁止其他中斷,防止中斷的嵌套。EnableQSCIReInt(0)使能QSCI0接收中斷。EnInt(2)使能2,3級別的中斷。主函數和中斷服務程序中的EnableInterrupt()作用是開放總中斷。 運行程序,從串口調試工具SSCOM V2.0發送字符“a”給MC56F8257,MC56F8257的QSCI0中斷接收,并將接收的數據發送給PC機,顯示串口調試工具窗口中,具體結果如圖2(a)所示。 如果屏蔽QSCI0接收中斷的默認優先級2,其主函數和QSCI接收中斷服務程序中的中斷代碼有所不同,具體見表4所示。 從表4看出,代碼EnInt(3)屏蔽了中斷優先級0、1和2,只允許優先級為3的中斷,無法響應優先級為2的QSCI0接收中斷。測試條件同上,其結果如圖4(b)所示。從圖4(b)看出,接收不到字符“a”。 (a)不屏蔽QSCI0接收中斷的結果 (b) 屏蔽QSCI0接收中斷的結果 圖4 不帶中斷優先級的QSCI0中斷接收結果 (2)帶中斷優先級 開放QSCI0接收中斷,設置其中斷優先級,不屏蔽該級別中斷,其主函數和中斷服務程序中的中斷代碼如表5所示。 從表5看出,代碼Qsci Priority的作用是設置QSCI0接收中斷優先級為0;EnInt(0)使能0,1,2,3級別的中斷。測試條件同上,其結果如圖3(a)所示。從圖3(a)看出,同樣也能接收到字符“a”。 如果屏蔽QSCI0接收中斷的優先級0,其主函數和QSCI接收中斷服務程序中的中斷代碼有所不同,具體見表6所示。 從表6看出,代碼EnInt(1) 屏蔽了中斷優先級0,允許優先級為1,2,3的中斷,因此QSCI0接收中斷被屏蔽,其測試結果如圖5(b)所示。從圖5(b)看出,同樣接收不到字符“a”。 (a)不屏蔽QSCI0接收中斷的結果 (b) 屏蔽QSCI0接收中斷的結果 圖5 帶中斷優先級的QSCI0中斷接收結果 (3)優先級嵌套 同時開放QSCI0接收中斷和CAN模塊接收中斷,并且前者優先級高于后者,其主函數和中斷服務程序中的中斷代碼如表7所示。 從表7看出,代碼Qsci Priority設定QSCI0接收中斷的優先級為1,CANPriority 設定CAN接收中斷的優先級為0,即QSCI0接收中斷的優先級高于CAN接收中斷。 運行程序,當僅有CAN接收中斷請求時,CAN接收中斷服務程序接收字符串“CANMessage”,并通過QSCI0將該字符發送給串口調試工具,如圖6(a)所示。如果在這個過程中,又有QSCI0接收中斷請求,CPU則暫停CAN接收中斷服務程序的執行,轉向QSCI0接收中斷服務程序處理,從串口調試工具窗口接收字符“a”,并發送給串口調試工具窗口。將QSCI0接收中斷服務程序執行完成后,返回CAN接收中斷服務程序繼續執行,其結果如圖6(a)所示。 如果開放QSCI0接收中斷和CAN模塊接收中斷,并且前者優先級低于后者,其主函數和中斷服務程序中的中斷代碼如表8所示。 從表8看出,代碼Qsci Priority設定QSCI0接收中斷的優先級為0,CANPriority設定CAN接收中斷的優先級為1,即QSCI0接收中斷的優先級低于CAN接收中斷。 運行程序,當僅有CAN接收中斷請求時,CAN接收中斷服務程序接收字符串“CANMessage”,并通過QSCI0將該字符發送給串口調試工具,如圖6(b)所示。如果在這個過程中,又有QSCI0接收中斷請求,CPU則不會響應其請求,繼續執行CAN接收中斷服務程序,繼續發送字符串“CANMessage” 給串口調試工具,如圖6(b)所示。 (a) QSCI0接收中斷優先級高于CAN模塊接收中斷 (b) QSCI0接收中斷優先級低于CAN模塊接收中斷 圖6 優先級嵌套時中斷處理結果 6.總結 本文以MC56F8257為例,分析DSC中斷系統,該系統具有處理多達67個中斷源的能力,并能夠給這些中斷源賦予不同的優先級,實現中斷嵌套,并提供標準和快速中斷處理兩種模式,這些特點促進其廣泛被應用。 上述特點也帶來中斷設置的靈活性,但是如果設置不當,會出現錯誤。本文在分析中斷系統的同時給出其中斷設置方法及過程,并詳細分析中斷優先級設置過程及注意事項。 最后,以MC56F8257中的QSCI模塊中斷及CAN模塊中斷為例,從不帶中斷優先級、帶中斷優先級和優先級嵌套三個方面,分析中斷設置過程及響應結果,結果分析進一步驗證MC56F8257中斷處理具有屏蔽及優先級可配置等特點。 |