新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32中斷管理函數

        STM32中斷管理函數

        作者: 時間:2016-11-28 來源:網絡 收藏
        CM3 內核支持256 個中斷,其中包含了16 個內核中斷和240 個外部中斷,并且具有256

        級的可編程中斷設置。但STM32 并沒有使用CM3 內核的全部東西,而是只用了它的一部分。
        STM32 有76 個中斷,包括16 個內核中斷和60 個可屏蔽中斷,具有16 級可編程的中斷優先級。
        而我們常用的就是這60 個可屏蔽中斷,所以我們就只針對這60 個可屏蔽中斷進行介紹。
        在 MDK 內,與NVIC相關的寄存器,MDK 為其定義了如下的結構體:
        typedef struct
        {
        vu32 ISER[2];
        u32 RESERVED0[30];
        vu32 ICER[2];
        u32 RSERVED1[30];
        vu32 ISPR[2];
        u32 RESERVED2[30];
        vu32 ICPR[2];
        u32 RESERVED3[30];
        vu32 IABR[2];
        u32 RESERVED4[62];
        vu32 IPR[15];
        } NVIC_TypeDef;
        STM32 的中斷在這些寄存器的控制下有序的執行的。了解這些中斷寄存器,你才能方便的
        使用STM32 的中斷。下面重點介紹這幾個寄存器:
        ISER[2]:ISER 全稱是:Interrupt Set-Enable Registers,這是一個中斷使能寄存器組。上面
        說了STM32 的可屏蔽中斷只有60 個,這里用了2 個32 位的寄存器,總共可以表示64 個中斷。
        而STM32 只用了其中的前60 位。ISER[0]的bit0~bit31 分別對應中斷0~31。ISER[1]的bit0~27
        對應中斷32~59;這樣總共60 個中斷就分別對應上了。你要使能某個中斷,必須設置相應的ISER
        位為1,使該中斷被使能(這里僅僅是使能,還要配合中斷分組、屏蔽、IO 口映射等設置才算是
        一個完整的中斷設置)。具體每一位對應哪個中斷,請參考stm32f10x_nvic..h 里面的第36 行處。
        ICER[2]:全稱是:Interrupt Clear-Enable Registers,是一個中斷除能寄存器組。該寄存器組
        與ISER 的作用恰好相反,是用來清除某個中斷的使能的。其對應位的功能,也和ICER 一樣。
        這里要專門設置一個ICER 來清除中斷位,而不是向ISER 寫0 來清除,是因為NVIC 的這些寄
        存器都是寫1 有效的,寫0 是無效的。具體為什么這么設計,請看《CM3 權威指南》第125 頁,
        NVIC 概覽一章。
        ISPR[2]:全稱是:Interrupt Set-Pending Registers,是一個中斷掛起控制寄存器組。每個位
        對應的中斷和ISER 是一樣的。通過置1,可以將正在進行的中斷掛起,而執行同級或更高級別
        的中斷。寫0 是無效的。
        ICPR[2]:全稱是:Interrupt Clear-Pending Registers,是一個中斷解掛控制寄存器組。其作
        用與ISPR 相反,對應位也和ISER 是一樣的。通過設置1,可以將掛起的中斷接掛。寫0 無效。
        IABR[2]:全稱是:Active Bit Registers,是一個中斷激活標志位寄存器組。對應位所代表

        本文引用地址:http://www.104case.com/article/201611/322721.htm

        的中斷和ISER 一樣,如果為1,則表示該位所對應的中斷正在被執行。這是一個只讀寄存器,
        通過它可以知道當前在執行的中斷是哪一個。在中斷執行完了由硬件自動清零。
        IPR[15]:全稱是:Interrupt Priority Registers,是一個中斷優先級控制的寄存器組。這個寄
        存器組相當重要!STM32 的中斷分組與這個寄存器組密切相關。IPR 寄存器組由15 個32bit 的
        寄存器組成,每個可屏蔽中斷占用8bit,這樣總共可以表示15*4=60 個可屏蔽中斷。剛好和
        STM32 的可屏蔽中斷數相等。IPR[0]的[31~24],[23~16],[15~8],[7~0]分別對應中中斷3~0,
        依次類推,總共對應60 個外部中斷。而每個可屏蔽中斷占用的8bit 并沒有全部使用,而是只
        用了高4 位。這4 位,又分為搶占優先級和子優先級。搶占優先級在前,子優先級在后。而這
        兩個優先級各占幾個位又要根據SCB->AIRCR 中中斷分組的設置來決定。
        這里簡單介紹一下 STM32 的中斷分組:STM32 將中斷分為5 個組,組0~4。該分組的設
        置是由SCB->AIRCR 寄存器的bit10~8 來定義的。具體的分配關系如下表所示:

        通過這個表,我們就可以清楚的看到組 0~4 對應的配置關系,例如組設置為3,那么此時
        所有的60 個中斷,每個中斷的中斷優先寄存器的高四位中的最高3 位是搶占優先級,低1 位是
        響應優先級。每個中斷,你可以設置搶占優先級為0~7,響應優先級為1 或0。搶占優先級的
        級別高于響應優先級。而數值越小所代表的優先級就越高。
        結合實例說明一下:假定設置中斷優先級組為2,然后設置中斷3(RTC 中斷)的搶占優先級
        為3,響應優先級為1。中斷6(外部中斷0)的搶占優先級為4,響應優先級為0。中斷7(外
        部中斷1)的搶占優先級為3,響應優先級為0。那么這3 個中斷的優先級順序為:中斷7>中
        斷3>中斷6。
        這里需要注意 2 點:
        如果兩個中斷的響應優先級和響應優先級都是一樣的話,則看哪個中斷先發生就先執行。
        高優先級的搶占優先級是可以打斷正在進行的低搶占優先級中斷的。而搶占優先級相同的
        中斷,高優先級的響應優先級不可以打斷低響應優先級的中斷。上面例子中的中斷3 和中斷7
        都可以打斷中斷6 的中斷。而中斷7 和中斷3 卻不可以相互打斷!
        通過以上介紹,我們熟悉了 STM32 中斷設置的大致過程。接下來我們介紹如何使用函數
        實現以上中斷設置,使得我們以后的中斷設置簡單化。
        第一個介紹的是NVIC 的分組函數MY_NVIC_PriorityGroupConfig,該函數的參數
        NVIC_Group 為要設置的分組號,可選范圍為0~4,總共5 組。如果參數非法,將可能導致不
        可預料的結果。MY_NVIC_PriorityGroupConfig 函數代碼如下:
        //設置NVIC 分組
        //NVIC_Group:NVIC 分組 0~4 總共5 組
        void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
        {
        u32 temp,temp1;
        temp1=(~NVIC_Group)&0x07;//取后三位
        temp1<<=8;
        temp=SCB->AIRCR; //讀取先前的設置
        temp&=0X0000F8FF; //清空先前分組
        temp|=0X05FA0000; //寫入鑰匙
        temp|=temp1;
        SCB->AIRCR=temp; //設置分組
        }
        通過前面的介紹,我們知道STM32 的5 個分組是通過設置SCB->AIRCR 的BIT[10:8]來實
        現的,而通過2.7.2.1 的介紹我們知道SCB->AIRCR 的修改需要通過在高16 位寫入0X05FA 這
        個密鑰才能修改的,故在設置AIRCR 之前,應該把密鑰加入到要寫入的內容的高16 位,以保
        證能正常的寫入AIRCR。在修改AIRCR 的時候,我們一般采用讀->改->寫的步驟,來實現不
        改變AIRCR 原來的其他設置。以上就是MY_NVIC_PriorityGroupConfig 函數設置中斷優先級分
        組的思路。
        第 二 個 函 數 是NVIC 設置函數MY_NVIC_Init , 該函數有4 個參數, 分別為:
        NVIC_PreemptionPriority 、NVIC_SubPriority 、NVIC_Channel 、NVIC_Group 。第一個參數
        NVIC_PreemptionPriority 為中斷搶占優先級數值,第二個參數NVIC_SubPriority 為中斷子優先
        級數值,前兩個參數的值必須在規定范圍內,否則也可能產生意想不到的錯誤。第三個參數
        NVIC_Channel 為中斷的編號(范圍為0~59),最后一個參數NVIC_Group 為中斷分組設置(范
        圍為0~4)。該函數代碼如下:
        //設置NVIC
        //NVIC_PreemptionPriority:搶占優先級
        //NVIC_SubPriority :響應優先級
        //NVIC_Channel :中斷編號
        //NVIC_Group :中斷分組 0~4
        //注意優先級不能超過設定的組的范圍!否則會有意想不到的錯誤
        //組劃分:
        //組0:0 位搶占優先級,4 位響應優先級
        //組1:1 位搶占優先級,3 位響應優先級
        //組2:2 位搶占優先級,2 位響應優先級
        //組3:3 位搶占優先級,1 位響應優先級
        //組4:4 位搶占優先級,0 位響應優先級
        //NVIC_SubPriority 和NVIC_PreemptionPriority 的原則是,數值越小,越優先
        void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,
        u8 NVIC_Group)
        {
        u32 temp;
        u8 IPRADDR=NVIC_Channel/4; //每組只能存4 個,得到組地址
        u8 IPROFFSET=NVIC_Channel%4;//在組內的偏移
        IPROFFSET=IPROFFSET*8+4; //得到偏移的確切位置
        MY_NVIC_PriorityGroupConfig(NVIC_Group);//設置分組
        temp=NVIC_PreemptionPriority<<(4-NVIC_Group);
        temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
        temp&=0xf;//取低四位
        if(NVIC_Channel<32)NVIC->ISER[0]|=1<相反操作就OK)
        else NVIC->ISER[1]|=1<<(NVIC_Channel-32);
        NVIC->IPR[IPRADDR]|=temp<}
        通過前面的介紹,我們知道每個可屏蔽中斷的優先級的設置是在IPR 寄存器組里面的,每
        個中斷占8 位,但只用了其中的4 個位,以上代碼就是根據中斷分組情況,來設置每個中斷對
        應的高4 位的數值的。當然在該函數里面還引用了MY_NVIC_PriorityGroupConfig 這個函數來
        設置分組。其實這個分組函數在每個系統里面只要設置一次就夠了,設置多次,則是以最后的
        那一次為準。但是只要多次設置的組號都是一樣,就沒事。否則前面設置的中斷會因為后面組
        的變化優先級會發生改變,這點在使用的時候要特別注意!一個系統代碼里面,所有的中斷分
        組都要統一!!,以上代碼對要配置的中斷號默認是開啟中斷的。也就是ISER 中的值設置為1
        了。
        上一頁 1 2 下一頁

        關鍵詞: STM32中斷管理函

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 花莲市| 泗洪县| 商丘市| 南昌县| 灵宝市| 清河县| 阿坝县| 文安县| 克东县| 桂林市| 九江市| 莒南县| 元谋县| 永州市| 成都市| 错那县| 文昌市| 和平县| 平度市| 信丰县| 土默特右旗| 元朗区| 德格县| 舞阳县| 高阳县| 淳化县| 蒙山县| 清苑县| 清新县| 崇文区| 贺州市| 香港| 岑巩县| 河间市| 肥西县| 礼泉县| 平潭县| 清远市| 赤水市| 九龙城区| 贵溪市|