新聞中心

        STM32中斷管理函數(shù)

        作者: 時(shí)間:2016-11-28 來(lái)源:網(wǎng)絡(luò) 收藏
        CM3 內(nèi)核支持256 個(gè)中斷,其中包含了16 個(gè)內(nèi)核中斷和240 個(gè)外部中斷,并且具有256

        級(jí)的可編程中斷設(shè)置。但STM32 并沒(méi)有使用CM3 內(nèi)核的全部東西,而是只用了它的一部分。
        STM32 有76 個(gè)中斷,包括16 個(gè)內(nèi)核中斷和60 個(gè)可屏蔽中斷,具有16 級(jí)可編程的中斷優(yōu)先級(jí)。
        而我們常用的就是這60 個(gè)可屏蔽中斷,所以我們就只針對(duì)這60 個(gè)可屏蔽中斷進(jìn)行介紹。
        在 MDK 內(nèi),與NVIC相關(guān)的寄存器,MDK 為其定義了如下的結(jié)構(gòu)體:
        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 的中斷在這些寄存器的控制下有序的執(zhí)行的。了解這些中斷寄存器,你才能方便的
        使用STM32 的中斷。下面重點(diǎn)介紹這幾個(gè)寄存器:
        ISER[2]:ISER 全稱是:Interrupt Set-Enable Registers,這是一個(gè)中斷使能寄存器組。上面
        說(shuō)了STM32 的可屏蔽中斷只有60 個(gè),這里用了2 個(gè)32 位的寄存器,總共可以表示64 個(gè)中斷。
        而STM32 只用了其中的前60 位。ISER[0]的bit0~bit31 分別對(duì)應(yīng)中斷0~31。ISER[1]的bit0~27
        對(duì)應(yīng)中斷32~59;這樣總共60 個(gè)中斷就分別對(duì)應(yīng)上了。你要使能某個(gè)中斷,必須設(shè)置相應(yīng)的ISER
        位為1,使該中斷被使能(這里僅僅是使能,還要配合中斷分組、屏蔽、IO 口映射等設(shè)置才算是
        一個(gè)完整的中斷設(shè)置)。具體每一位對(duì)應(yīng)哪個(gè)中斷,請(qǐng)參考stm32f10x_nvic..h 里面的第36 行處。
        ICER[2]:全稱是:Interrupt Clear-Enable Registers,是一個(gè)中斷除能寄存器組。該寄存器組
        與ISER 的作用恰好相反,是用來(lái)清除某個(gè)中斷的使能的。其對(duì)應(yīng)位的功能,也和ICER 一樣。
        這里要專門設(shè)置一個(gè)ICER 來(lái)清除中斷位,而不是向ISER 寫0 來(lái)清除,是因?yàn)镹VIC 的這些寄
        存器都是寫1 有效的,寫0 是無(wú)效的。具體為什么這么設(shè)計(jì),請(qǐng)看《CM3 權(quán)威指南》第125 頁(yè),
        NVIC 概覽一章。
        ISPR[2]:全稱是:Interrupt Set-Pending Registers,是一個(gè)中斷掛起控制寄存器組。每個(gè)位
        對(duì)應(yīng)的中斷和ISER 是一樣的。通過(guò)置1,可以將正在進(jìn)行的中斷掛起,而執(zhí)行同級(jí)或更高級(jí)別
        的中斷。寫0 是無(wú)效的。
        ICPR[2]:全稱是:Interrupt Clear-Pending Registers,是一個(gè)中斷解掛控制寄存器組。其作
        用與ISPR 相反,對(duì)應(yīng)位也和ISER 是一樣的。通過(guò)設(shè)置1,可以將掛起的中斷接掛。寫0 無(wú)效。
        IABR[2]:全稱是:Active Bit Registers,是一個(gè)中斷激活標(biāo)志位寄存器組。對(duì)應(yīng)位所代表

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

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

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

        關(guān)鍵詞: STM32中斷管理函

        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 宁都县| 郁南县| 广宁县| 喀什市| 绩溪县| 上饶市| 宁南县| 民勤县| 湘潭市| 江源县| 安远县| 五家渠市| 龙山县| 满城县| 云阳县| 南汇区| 株洲市| 井陉县| 邵东县| 深泽县| 普陀区| 鲁山县| 库尔勒市| 威宁| 齐齐哈尔市| 昌图县| 恩施市| 丰都县| 湖北省| 红原县| 长葛市| 梁山县| 新密市| 邵武市| 常熟市| 东乡族自治县| 法库县| 读书| 海原县| 柘城县| 牙克石市|