新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32 NVIC 中斷優先級管理

        STM32 NVIC 中斷優先級管理

        作者: 時間:2016-11-11 來源:網絡 收藏
        CM3內核支持256個中斷,其中包含了16個內核中斷和240個外部中斷,并且具有256級的可編程中斷設置。但STM32并沒有使用CM3內核的全部東西,而是只用了它的一部分。STM32有84個中斷,包括16個內核中斷和68個可屏蔽中斷,具有16級可編程的中斷優先級。而我們常用的就是這68個可屏蔽中斷,但是STM32的68個可屏蔽中斷,在STM32F103系列上面,又只有60個(在107系列才有68個)。

        在MDK內,與NVIC相關的寄存器,MDK為其定義了如下的結構體:

        本文引用地址:http://www.104case.com/article/201611/317044.htm
        1.   typedefstruct
        2.   {
        3.   vu32 ISER[2];
        4.   u32 RESERVED0[30];
        5.   vu32 ICER[2];
        6.   u32 RSERVED1[30];
        7.   vu32 ISPR[2];
        8.   u32 RESERVED2[30];
        9.   vu32 ICPR[2];
        10.   u32 RESERVED3[30];
        11.   vu32 IABR[2];
        12.   u32 RESERVED4[62];
        13.   vu32 IPR[15];
        14.   }NVIC_TypeDef;

        STM32的中斷在這些寄存器的控制下有序的執行的。只有了解這些中斷寄存器,才能了解STM32的中斷。下面簡要介紹這幾個寄存器:

        ISER[2]:ISER全稱是:InterruptSet-EnableRegisters,這是一個中斷使能寄存器組。上面說了STM32F103的可屏蔽中斷只有60個,這里用了2個32位的寄存器,總共可以表示64個中斷。而STM32F103只用了其中的前60位。ISER[0]的bit0~bit31分別對應中斷0~31。ISER[1]的bit0~27對應中斷32~59;這樣總共60個中斷就分別對應上了。你要使能某個中斷,必須設置相應的ISER位為1,使該中斷被使能(這里僅僅是使能,還要配合中斷分組、屏蔽、IO口映射等設置才算是一個完整的中斷設置)。具體每一位對應哪個中斷,請參考stm32f10x_nvic..h里面的第36行處。

        ICER[2]:全稱是:InterruptClear-EnableRegisters,是一個中斷除能寄存器組。該寄存器組與ISER的作用恰好相反,是用來清除某個中斷的使能的。其對應位的功能,也和ICER一樣。這里要專門設置一個ICER來清除中斷位,而不是向ISER寫0來清除,是因為NVIC的這些寄存器都是寫1有效的,寫0是無效的。

        ISPR[2]:全稱是:InterruptSet-PendingRegisters,是一個中斷掛起控制寄存器組。每個位對應的中斷和ISER是一樣的。通過置1,可以將正在進行的中斷掛起,而執行同級或更高級別的中斷。寫0是無效的。

        ICPR[2]:全稱是:InterruptClear-PendingRegisters,是一個中斷解掛控制寄存器組。其作用與ISPR相反,對應位也和ISER是一樣的。通過設置1,可以將掛起的中斷接掛。寫0無效。

        IABR[2]:全稱是:InterruptActiveBitRegisters,是一個中斷激活標志位寄存器組。這是一個只讀寄存器,通過它可以知道當前在執行的中斷是哪一個。在中斷執行完了由硬件自動清零。對應位所代表的中斷和ISER一樣,如果為1,則表示該位所對應的中斷正在被執行。

        IPR[15]:全稱是:InterruptPriorityRegisters,是一個中斷優先級控制的寄存器組。這個寄存器組相當重要!STM32的中斷分組與這個寄存器組密切相關。因為STM32的中斷多達60多個,所以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。搶占優先級的級別高于響應優先級。而數值越小所代表的優先級就越高。

        這里需要注意兩點:第一,如果兩個中斷的搶占優先級和響應優先級都是一樣的話,則看哪個中斷先發生就先執行;第二,高優先級的搶占優先級是可以打斷正在進行的低搶占優先級中斷的。而搶占優先級相同的中斷,高優先級的響應優先級不可以打斷低響應優先級的中斷。

        使用庫函數實現以上中斷分組設置以及中斷優先級管理,使得我們以后的中斷設置簡單化。NVIC中斷管理函數主要在misc.c文件里面。

        首先是中斷優先級分組函數NVIC_PriorityGroupConfig,這個函數的作用是對中斷的優先級進行分組,這個函數在系統中只能被調用一次,一旦分組確定就最好不要更改。

        比如我們設置整個系統的中斷優先級分組值為2(2位搶占優先級,2位響應優先級”),那么方法是:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

        設置好了系統中斷分組,那么對于每個中斷又怎么確定他的搶占優先級和響應優先級呢?下面看一個重要的函數為中斷初始化函數NVIC_Init,其函數申明為:

        voidNVIC_Init(NVIC_InitTypeDef*NVIC_InitStruct)

        其中NVIC_InitTypeDef是一個結構體,可以看看結構體的成員變量:

        1.    typedefstruct
        2.    {
        3.      uint8_t NVIC_IRQChannel;//定義初始化的是哪個中斷,這個我們可以在 stm32f10x.h 中找到每個中斷對應的名字。例如 USART1_IRQn。
        4.      uint8_t NVIC_IRQChannelPreemptionPriority;//定義這個中斷的搶占優先級別。
        5.      uint8_t NVIC_IRQChannelSubPriority;//定義這個中斷的子優先級別。
        6.      FunctionalState NVIC_IRQChannelCmd;//該中斷是否使能。
        7.    }NVIC_InitTypeDef;

        比如我們要使能串口1的中斷,同時設置搶占優先級為1,子優先級位2,初始化的方法是:

        1.    USART_InitTypeDef USART_InitStructure;
        2.    NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//串口 1 中斷
        3.    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;// 搶占優先級為 1
        4.    NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;// 子優先級位 2
        5.    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//IRQ 通道使能
        6.    NVIC_Init(&NVIC_InitStructure);



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 鹤壁市| 江城| 玉环县| 成武县| 宣化县| 三原县| 聂荣县| 忻城县| 金山区| 久治县| 宁夏| 应用必备| 内乡县| 喀喇沁旗| 内江市| 光山县| 新源县| 扬州市| 且末县| 西乌珠穆沁旗| 雅江县| 灯塔市| 宁津县| 治县。| 习水县| 揭东县| 辉县市| 东台市| 湘阴县| 宁安市| 屯门区| 牟定县| 泸水县| 德清县| 瑞丽市| 通州市| 马龙县| 忻州市| 元谋县| 伊吾县| 台北县|