MCU中斷處理那些事(二)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
前述文章,MCU中斷處理那些事(一)中,我們簡(jiǎn)要介紹了16位MCU的中斷處理系統(tǒng)的基本特點(diǎn),本文基于上一次的話(huà)題繼續(xù)討論中斷相關(guān)的事情。
一.MCU的中斷處理過(guò)程
當(dāng)一個(gè)中斷事件發(fā)生時(shí),它主要經(jīng)歷這樣一個(gè)過(guò)程:首先是外設(shè)硬件或者MCU內(nèi)核檢測(cè)到這個(gè)事件,如果這個(gè)中斷的優(yōu)先級(jí)高于當(dāng)前CPU的優(yōu)先級(jí),當(dāng)前的程序執(zhí)行就會(huì)停下來(lái),接著就開(kāi)啟了中斷服務(wù)程序ISR.
當(dāng)中斷服務(wù)程序執(zhí)行完成時(shí),硬件會(huì)恢復(fù)先前停止的程序運(yùn)行,接著執(zhí)行停下來(lái)時(shí)的下一條指令。
二.中斷的分類(lèi)
16位MCU會(huì)識(shí)別兩種不同的中斷類(lèi)型,其中一種是不可以mask的Traps事件。這里我們?cè)敿?xì)了解一下Traps。Traps是一些不可以mask的,可以嵌套的中斷。這些中斷具有固定的中斷優(yōu)先級(jí)。他們存在的意義主要是檢測(cè)并糾正一定的硬件和軟件問(wèn)題。
圖1 Traps存在的意義
當(dāng)用戶(hù)不想去糾正一些Trap錯(cuò)誤條件時(shí),中斷向量會(huì)指向讓器件復(fù)位的代碼,否則用戶(hù)應(yīng)用代碼需要編程Trap中斷向量指向糾正Trap條件的代碼。
圖2 Traps的種類(lèi)
在dsPIC33及PIC24芯片上主要有以上幾種Trap事件。一般來(lái)說(shuō),在Trap中斷服務(wù)程序開(kāi)始前,引起Trap的指令是允許執(zhí)行完成的,所以用戶(hù)需要考慮引起Traps的指令導(dǎo)致的一些影響。
對(duì)于Trap事件來(lái)說(shuō),他們具有固定的優(yōu)先級(jí),如振蕩器失效的Trap的優(yōu)先級(jí)最高,而DMAC錯(cuò)誤的優(yōu)先級(jí)最低。Trap的源是可以分為兩類(lèi)的,一類(lèi)是Hard Trap,另一類(lèi)是Soft Trap,大家需要注意。
除了Trap類(lèi)型的中斷之外,就是外設(shè)和I/O的外部中斷。這些中斷是屬于一般的,可以被mask的中斷,這些中斷源都是來(lái)源于硬件外設(shè)的申請(qǐng),例如外部中斷pin,比較器中斷,通信接口I2C或者UART中斷等。
三.CPU的中斷優(yōu)先級(jí)
16位MCU的中斷處理系統(tǒng)的一個(gè)關(guān)鍵特性是,用戶(hù)可以對(duì)中斷優(yōu)先級(jí)進(jìn)行設(shè)定,包括外設(shè)中斷和外部中斷等,對(duì)于此,我們先了解一下CPU的中斷優(yōu)先級(jí)的設(shè)定方式。
CPU的優(yōu)先級(jí)可以設(shè)定為0-15這個(gè)范圍的共16個(gè)優(yōu)先級(jí)水平,所以,中斷進(jìn)行響應(yīng)處理的一個(gè)前提是,中斷的優(yōu)先級(jí)必須要高于CPU的當(dāng)前的優(yōu)先級(jí)。
外設(shè)或者外部中斷的優(yōu)先級(jí)可以設(shè)定為0-7這些優(yōu)先級(jí)水平,而需要注意的是CPU的8-15的優(yōu)先級(jí)部分是為Traps事件所保留且是固定的。
當(dāng)前執(zhí)行線(xiàn)程的CPU的優(yōu)先級(jí)是由CPU的狀態(tài)寄存器SR中的IPL位及Core的控制寄存器中的IPL3所決定,如圖3和4。
圖3 CPU的SR寄存器中的IPL位
圖4 CORCON寄存器的IPL3位
圖5 CPU優(yōu)先級(jí)的設(shè)定示例
如果我們將CPU的優(yōu)先級(jí)設(shè)定為7,則所有的用戶(hù)中斷將被disable,因?yàn)樗械耐庠O(shè)及外部中斷優(yōu)先級(jí)不可能大于7.而IPL3這一位被系統(tǒng)設(shè)定為了1,意味著發(fā)生了Trap事件。
這里,有一個(gè)知識(shí)點(diǎn)需要注意,就是當(dāng)器件復(fù)位后,CPU的優(yōu)先級(jí)是默認(rèn)為0的,也就是說(shuō)它比任何優(yōu)先級(jí)非0的外設(shè)中斷和外部中斷的優(yōu)先級(jí)都要低,它是允許用戶(hù)中斷的。
那么,我們?nèi)绾闻渲?/span>CPU的優(yōu)先級(jí)呢?首先IPL是可以根據(jù)用戶(hù)的需要手動(dòng)配置的,它可以允許配置為7,允許系統(tǒng)在一段時(shí)間內(nèi)mask所有的外設(shè)和外部中斷,以便密集執(zhí)行一些CPU命令。
而IPL3是被CPU Core所設(shè)置的,它在發(fā)生Trap事件時(shí),自動(dòng)會(huì)設(shè)置為1.
四.中斷的嵌套功能
中斷處理系統(tǒng)不得不提的一個(gè)特性,就是中斷嵌套,在默認(rèn)設(shè)置下,16位MCU是允許中斷嵌套功能的,任何一個(gè)高優(yōu)先級(jí)的中斷都可以打斷一個(gè)低優(yōu)先級(jí)的中斷復(fù)位程序,去執(zhí)行高優(yōu)先級(jí)的中斷服務(wù)程序。
這里我們有一個(gè)示例,用以說(shuō)明中斷嵌套的執(zhí)行,如圖6所示。
圖6 中斷嵌套示例
這里假定,當(dāng)在主程序main執(zhí)行任務(wù)時(shí),有不同的優(yōu)先級(jí)的三個(gè)ISR執(zhí)行,此處使能了中斷嵌套功能,可以看到由于CPU的優(yōu)先級(jí)是0,所以?xún)?yōu)先級(jí)為4的中斷打斷了CPU去執(zhí)行其任務(wù),在執(zhí)行過(guò)程中,優(yōu)先級(jí)為7的中斷觸發(fā)了,所以?xún)?yōu)先執(zhí)行這個(gè)7優(yōu)先級(jí)中斷,在此過(guò)程中,優(yōu)先級(jí)為1的中斷觸發(fā)了,但是其優(yōu)先級(jí)太低,所以排隊(duì)在后面再執(zhí)行。7優(yōu)先級(jí)中斷任務(wù)執(zhí)行完之后,接著執(zhí)行4優(yōu)先級(jí)未執(zhí)行完的任務(wù),最終4優(yōu)先級(jí)的中斷執(zhí)行完成,最后執(zhí)行1優(yōu)先級(jí)的任務(wù)。這就是一個(gè)中斷嵌套的典型示例。
這里有一個(gè)知識(shí)點(diǎn)需要注意,在中斷嵌套允許時(shí),由于低優(yōu)先級(jí)的中斷可能會(huì)被打斷,所以其中斷延時(shí)會(huì)發(fā)生延長(zhǎng)變化,比如它需要7個(gè)指令周期的中斷延時(shí),3個(gè)指令周期用于走出前面的中斷,四個(gè)指令周期用于進(jìn)入新的中斷。
當(dāng)用戶(hù)不希望中斷在執(zhí)行時(shí)被其它高優(yōu)先級(jí)中斷打斷時(shí),那么,可以disable中斷嵌套功能,具體可以在INTCON1中的NSTDIS位置位,這樣在一個(gè)中斷執(zhí)行時(shí),CPU的中斷優(yōu)先級(jí)會(huì)被強(qiáng)制為7,這就可以mask所有的其它中斷,直到系統(tǒng)收到當(dāng)前中斷執(zhí)行完成的標(biāo)志,則可以執(zhí)行其它中斷,此時(shí)需要執(zhí)行當(dāng)時(shí)pending發(fā)生的最高優(yōu)先級(jí)的中斷。關(guān)于中斷嵌套使能的功能這一個(gè)設(shè)置如圖7所示。
圖7 中斷嵌套的mask
五.中斷沖突的解決
當(dāng)多個(gè)中斷源同時(shí)發(fā)生時(shí),且他們的中斷優(yōu)先級(jí)都是一樣的值,比如,他們被設(shè)為初始化時(shí)的中斷優(yōu)先級(jí)4,那么此時(shí)如何解決他們的沖突呢?需要先執(zhí)行響應(yīng)誰(shuí)呢?
事實(shí)上,每一個(gè)中斷源都有一個(gè)自然優(yōu)先級(jí),這個(gè)自然優(yōu)先級(jí)取決于這個(gè)中斷向量在中斷向量表IVT上的位置,越小編號(hào)的中斷向量,其自然優(yōu)先級(jí)越高。
圖8 中斷向量的自然優(yōu)先級(jí)
所以,當(dāng)出現(xiàn)同一個(gè)用戶(hù)設(shè)定的優(yōu)先級(jí)沖突時(shí),可以以自然優(yōu)先級(jí)的順序來(lái)執(zhí)行中斷申請(qǐng),如圖8所示。
總的說(shuō)來(lái),解決中斷沖突,需要首先看用戶(hù)指定的中斷優(yōu)先級(jí),這個(gè)在IPC寄存器中設(shè)置,如果若干中斷的優(yōu)先級(jí)一樣,那么需要以自然優(yōu)先級(jí)為順序去響應(yīng)中斷。
六.中斷功能的使用
在代碼中使用一個(gè)中斷,需要注意三個(gè)寄存器的使用,中斷標(biāo)志位IF,中斷使能位IE,中斷優(yōu)先級(jí)位IPC,中斷控制器會(huì)接收所有的中斷申請(qǐng)并判斷其優(yōu)先級(jí),然后發(fā)給CPU一個(gè)唯一的中斷申請(qǐng)?jiān)?,及其?yōu)先級(jí)信息,如圖9所示。
圖9 中斷控制器的功能
這里,可以看出Trap的中斷優(yōu)先級(jí)為8-15,在發(fā)生Trap時(shí)CPU的CORCON寄存器中的IPL3自動(dòng)設(shè)為1,表示這是Trap的發(fā)生。
需要使用一個(gè)中斷,首先應(yīng)該使能這個(gè)中斷,比如,此處以外部中斷INT0為例,將INT0IE設(shè)為1使能這個(gè)中斷。
圖10 中斷使能示例
需要注意的是,使能中斷和設(shè)置中斷的優(yōu)先級(jí)的順序需要注意,一般不推薦在中斷使能后,再去改變中斷的優(yōu)先級(jí),這會(huì)導(dǎo)致在中斷發(fā)生時(shí)去改變其優(yōu)先級(jí),那么可能會(huì)丟失這個(gè)中斷,或者使用了錯(cuò)誤的優(yōu)先級(jí)。正確的做法是先disable中斷,設(shè)定其優(yōu)先級(jí),再使能中斷。
圖11 中斷的優(yōu)先級(jí)設(shè)定
中斷的優(yōu)先級(jí)設(shè)定使用IPC寄存器,此處以INT0中斷優(yōu)先級(jí)設(shè)定為例說(shuō)明,如圖11所示,通過(guò)三位的優(yōu)先級(jí)設(shè)定位,可以設(shè)定0-7的優(yōu)先級(jí)水平,值得注意的是,當(dāng)中斷優(yōu)先級(jí)設(shè)為0時(shí),這個(gè)中斷是不被響應(yīng)的,相當(dāng)于disable了這個(gè)中斷。
圖12 中斷標(biāo)志位
當(dāng)一個(gè)中斷或者事件發(fā)生時(shí),中斷標(biāo)志位會(huì)置位為1,在用戶(hù)中斷服務(wù)程序中可以將其清零,作為用戶(hù)程序?qū)Υ酥袛嗟膽?yīng)答。
七.中斷服務(wù)程序相關(guān)的討論
標(biāo)準(zhǔn)的C語(yǔ)言規(guī)范并沒(méi)有說(shuō)明如何去聲明一個(gè)函數(shù)作為中斷服務(wù)程序,MPLAB的XC16對(duì)中斷屬性進(jìn)行了特殊定義,用于申明一個(gè)函數(shù)作為中斷服務(wù)程序。這里我們以INT0中斷為例說(shuō)明。
圖13 中斷服務(wù)程序?qū)傩月暶魇纠?/span>
在XC16的編譯器用戶(hù)手冊(cè)中或者芯片規(guī)格書(shū)中,我們可以找到中斷服務(wù)程序預(yù)定義的名字,如圖14,15所示(注:并非完整表格,僅僅截圖示意)。
圖14 編譯器定義的中斷服務(wù)程序名稱(chēng)
圖15 編譯器定義的中斷服務(wù)程序名稱(chēng)2
從上面的INT0中斷服務(wù)程序ISR來(lái)看,它的特點(diǎn)主要如下:
§ 沒(méi)有參數(shù);
§ void返回類(lèi)型;
§ 必須使用在XC16中定義的名字;
§ 不能在main函數(shù)中調(diào)用;
在中斷使能后,中斷可能在任何時(shí)候發(fā)生,所以它會(huì)破壞主程序原有使用的變量,16位單片機(jī)的硬件中斷處理器提供了一種機(jī)制,在堆棧中去保存和恢復(fù)CPU的背景內(nèi)容。其中PC指針,PCH,PCL及CPU狀態(tài)寄存器的低位字節(jié)部分SRL,是自動(dòng)在堆棧中存儲(chǔ)和恢復(fù)的。如圖16所示。
圖16 CPU背景保存和恢復(fù)
同時(shí)XC16還可以用額外的背景保存指令,保存和恢復(fù)諸如RCOUNT,W0-W13,W14,PSVPAG等寄存器內(nèi)容。除此之外,還可以通過(guò)編譯器的save屬性去保存和恢復(fù)一些關(guān)心的變量,如圖17所示。
圖17 變量的保存和恢復(fù)
總結(jié),本文延續(xù)前述文章,在中斷處理系統(tǒng)初步介紹的基礎(chǔ)上,去進(jìn)一步探討了中斷的處理過(guò)程,中斷的優(yōu)先級(jí),CPU的優(yōu)先級(jí),及中斷的嵌套功能及如何處理中斷沖突,最后通過(guò)示例介紹了中斷的使用及中斷服務(wù)程序的一些要求,相對(duì)完整的對(duì)中斷處理有一個(gè)基本的認(rèn)識(shí),為后續(xù)進(jìn)一步深入探討奠定基礎(chǔ)。





