專(zhuān)注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

STM32 NVIC嵌套向量中斷控制器函數(shù)分析

作者:佚名   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2013年10月22日   【字體:
中斷管理函數(shù)
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;

ISER[2]:Interrupt set enable registers 中斷使能寄存器組
ICER[2]:interrupt clear enable registers 中斷除能寄存器組
ISPR[2]:interrupt set pending registers 中斷掛起寄存器組
ICPR[2]: interrupt clear pending registers 中斷解掛寄存器組
IABR[2]:interrupt active bit registers 中斷激活標(biāo)志寄存器組

主要分析
IPR[15]:interrupt priority registers   中斷優(yōu)先級(jí)控制寄存器組




使用函數(shù)實(shí)現(xiàn)中斷分組:  可選分組0--4

MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
{
 u32 temp,temp1;                                              //設(shè)置中轉(zhuǎn)變量
temp1=(~NVIC_Group)&0x07;                          //取后3位
temp1<<=8;                                                     //左移8位
temp=SCB->AIRCR;                                        //讀取先前設(shè)置 
temp&=0x0000F8FF;                                       //清空先前設(shè)置
temp|=0x05FA0000;                                         //插入密鑰
temp|=temp1;                                                     //分組設(shè)置賦值進(jìn)
SCB->AIRCB=temp;                                           //設(shè)置完的值賦值給中斷分組寄存器
}

語(yǔ)句解讀:

             temp1=(~NVIC_Group)&0x07;      由于
 所以組號(hào)取反與111 即得到分組所需寄存器值
              temp|=0x05FA0000;     
密鑰


 使用函數(shù)實(shí)現(xiàn)中斷優(yōu)先級(jí)設(shè)置:
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);  //  設(shè)置搶占優(yōu)先級(jí)
temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);      //設(shè)置響應(yīng)優(yōu)先級(jí)
temp&=0xf;                                                                //取低4位
if(NVIC_Channel<32)  NVIC->ISER[0]|=1<<NVIC_Channel;                     //使能中斷位
else
                                   NVIC->ISER[1]|=1<<(NVIC_Channel-32);
NVIC->IPR[IPRADDR]|=temp<<IPROFFSET;                   //設(shè)置響應(yīng)優(yōu)先級(jí)和搶占優(yōu)先級(jí)


語(yǔ)句解讀:

               
u8 IPRADDR=NVIC_Channel/4;                //ISER[2]組可以設(shè)置60個(gè)中斷優(yōu)先級(jí),每組15個(gè)寄存器,每個(gè)寄存器32位  每個(gè)可中 斷8位,每個(gè)寄存器可以設(shè)置4個(gè)中斷,           組地址=channel/4;      //選擇中斷號(hào)組(0--3)(4--7),,,(56---59)
               u8 IPROFFSET=NVIC_Channel%4;          組內(nèi)偏移地址      //選擇第幾個(gè)中斷號(hào)
               
IPROFFSET=IPROFFSET*8+4;                 //由于每個(gè)中斷8位,只用了前4位,所以偏移4



             


             
 temp=NVIC_Preemptionpriority<<(4-NVIC_Group);      //搶占優(yōu)先級(jí)在左邊,根據(jù)搶占位多少進(jìn)行左移
               temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);          //響應(yīng)優(yōu)先級(jí)在右邊,根據(jù)響應(yīng)位多少進(jìn)行右移
               temp&=0xf;                                                                 //得到分組值

外部中斷配置函數(shù):

STM32的EXTI控制器支持19個(gè)外部中斷/事件請(qǐng)求。每個(gè)中斷設(shè)有狀態(tài)位,每個(gè)中斷/事件都有獨(dú)立的觸發(fā)和屏蔽設(shè)置。STM32的19個(gè)外部中斷為:
線0~15:對(duì)應(yīng)外部IO口的輸入中斷。
線16:連接到PVD輸出。 
            PVD(Programmable Voltage Detector),即可編程電壓監(jiān)測(cè)器。應(yīng)用于STM32ARM芯片中,作用是監(jiān)視供電電壓,在供電電壓下降到給定的閥值以下時(shí),產(chǎn)生一個(gè)中斷,通知軟件做緊急處理。當(dāng)供電電壓又恢復(fù)到給定的閥值以上時(shí),也會(huì)產(chǎn)生一個(gè)中斷,通知軟件供電恢復(fù)。

線17:連接到RTC鬧鐘事件。                   RTC是多種名詞的縮寫(xiě),如:實(shí)時(shí)時(shí)鐘(Real-Time Clock)
線18:連接到USB喚醒事件。
對(duì)于外部中斷EXTI控制MDK定義了如下結(jié)構(gòu)體:
typedef struct
{
vu32 IMR;
vu32 EMR;
vu32 RTSR;
vu32 FTSR;
vu32 SWIER;
vu32 PR;
} EXTI_TypeDef;


IMR:
中斷屏蔽寄存器Interrupt Mask Register         32位寄存器前19位有效
EMR: 事件屏蔽寄存器 Event mask register               32位寄存器前19位有效
RTST: 上升沿觸發(fā)選擇寄存器 Rising edge trigger select register
FTSR:下降沿觸發(fā)選擇寄存器 Falling edge trigger select register
SWIER:軟件中斷事件寄存器 Software interrupt event register
PR:   掛起寄存器 Pending Register

I/O口復(fù)用里的配置寄存器EXTICR     每個(gè)I/O口可以配置成中斷輸入


STM32 任何一個(gè)IO口都可以配置成中斷輸入口,但是IO口的數(shù)目遠(yuǎn)大于中斷線數(shù)(16個(gè))。于是STM32就這樣設(shè)計(jì),GPIOA~GPIOG的[15:0]分別對(duì)應(yīng)中斷線15~0。這樣每個(gè)中斷線對(duì)應(yīng)了最多7個(gè)IO口,以線0為例:它對(duì)應(yīng)了GPIOA.0、PIOB.0、GPIOC.0、GPIOD.0、 GPIOE.0、GPIOF.0、GPIOG.0。而中斷線每次只能連接到1個(gè)IO口上,這樣就需要EXTICR來(lái)決定對(duì)應(yīng)的中斷線配置到哪個(gè)GPIO上了。



 











EXTICR在AFIO的結(jié)構(gòu)體中定義如下

typedef struct
{
vu32 EVCR;
vu32 MAPR;
vu32 EXTICR[4];
} AFIO_TypeDef;

EXTIRC寄存器總共4個(gè),因?yàn)榫幾g器的寄存器都是從0號(hào)開(kāi)始的,所以EXTICR[0]---EXTICR[3]對(duì)應(yīng)
<<STM32參考手冊(cè)>>中的EXTICR1---EXTICR4 每個(gè)EXTICR用了其中低16位.

外部中斷配置函數(shù):
void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM)
{
 u8 EXTADDR;                                
 u8 EXTOFFSET;
 EXTADDR=BITx/4;                //得到中斷寄存器組編號(hào)

 EXTOFFSET=(BITx%4)*4;          //得到偏移量            具體哪個(gè)I/O口進(jìn)行設(shè)置                       
RCC->APB2ENR|=0x01;              //使能復(fù)用I/O口
AFIO->EXTICR[EXTADDR]|=GPIOx<<EXTOFFSET;      //EXTI.BITx映射到GPIOx.BITx中
EXTI->IMR|=1<<BITx;                              //開(kāi)啟中斷
EXTI->EMR|=1<<BITx;                             //不屏蔽事件中斷
if(TRIM&0x01)  EXIT->FTSR|=1<<BITx;            //下降沿觸發(fā)
if(TRIM&0x02) EXIT->RTSR|=1<<BITx;            //上升沿觸發(fā)

}

注:
      TRIM為觸發(fā)方式選擇變量; 0x01下降沿觸發(fā)   0x02 上升沿觸發(fā) 0x03任意電平觸發(fā).
關(guān)閉窗口

相關(guān)文章