STM32的中斷系統

來源:互聯網
上載者:User
STM32的中斷系統

STM32具有十分強大的中斷系統,將中斷分為了兩個類型:核心例外狀況和外部中斷。並將所有中斷通過一個表編排起來,下面是stm32中斷向量表的部分內容:

-3到6這個地區被標黑了,這個地區就是核心例外狀況。核心例外狀況不能夠被打斷,不能被設定優先權(也就是說優先順序是淩駕於外部中斷之上的)。常見的核心例外狀況有以下幾種:複位(reset),不可屏蔽中斷(NMI),硬性錯誤(Hardfault),其他的也可以在表上找到。

從第7個開始,後面所有的中斷都是外部中斷。外部中斷是我們必須學習掌握的知識,包含線中斷,定時器中斷,IIC,SPI等所有的外設中斷,可配置優先順序。外部中斷的優先順序分為兩種:搶佔優先順序和響應優先順序。

什麼是搶佔優先順序?

搶佔優先順序比較霸道,一言不和就插隊。搶佔優先順序高的,能夠打斷優先順序低的任務,等優先順序較高的任務執行完畢後,再回來繼續執行之前的任務。所以當存在多個搶佔優先順序不同的任務時,很有可能會產生任務的嵌套。

什麼是響應優先順序?

響應優先順序則稍微謙遜些,比較有禮貌。響應優先順序又被稱為次優先順序,若兩個任務的搶佔式優先順序一樣,那麼響應優先順序較高的任務則先執行,且在執行的同時不能被下一個響應優先順序更高的任務打斷,所以我說它比較有有禮貌。。

中斷控制器(NVIC)

因為stm32的中斷系統比較複雜,所以在核心中有一個專門管理中斷的控制器:NVIC.

NVIC負責除了SYSTICK之外的所有中斷的控制,十分重要!

在標準庫中,提供了一套通過NVIC來控制中斷的API,我們首先來看NVIC_Init()函數,這套函數首先要定義並填充一個結構體:NVIC_InitTypeDef 該結構體的定義如下:

NVIC_IRQChannel 需要配置的中斷向量

NVIC_IRQChannelCmd 使能或者關閉相應中斷向量的中斷響應

NVIC_IRQChannelPreemptionPriority 配置相應中斷向量的搶佔優先順序

NVIC_IRQChannelSubPriority 配置相應中斷的響應優先順序

結構體的四個成員都比較好理解,這裡就不再累述了。

不過要注意一點的是,NVIC只可以配置16種中斷向量的優先順序,其搶佔優先順序和響應優先順序都用一個4位的數字來決定。在庫函數中,將其分為了5中不同的分配方式:

第0組:所有的4位都有來表示響應優先順序,能夠配置16種不同的響應優先順序。中斷優先順序則都相同。

第1組:最高一位用來配置搶佔優先順序,剩餘三位用來表示響應優先順序。那麼就有兩種不同的搶佔優先順序(0和1)和8種不同的響應優先順序(0~7)。

第2組:高兩位用來配置搶佔優先順序,低位用來配置響應優先順序。那麼兩種優先順序就各有4種。

第3組:高三位用來配置搶佔優先順序,低位用來配置響應優先順序。有8種搶佔優先順序和2種相應優先順序。

第4組:所有位都用來配置搶佔優先順序,即有16種搶佔優先順序,沒有響應屬性。

這5種不同的分配方式,根據項目的實際需求來配置。

配置的API如下:

NVIC_PriorityGroupConfig();

其中括弧內可以輸入以下一個參數,代表不同的分配方式:

NVIC_PriorityGroup_0

NVIC_PriorityGroup_1

NVIC_PriorityGroup_2

NVIC_PriorityGroup_3

NVIC_PriorityGroup_4

EXTI外部中斷

STM32的所有GPIO都引入到了EXTI外部中斷線上,也就是說,所有的IO口經過配置後都能夠觸發中斷。就是GPIO和EXTI的串連方式:

從我們可以看出,一共有16個中斷線: EXTI0到EXTI15.

每個中斷線都對應了從PAx到PGx一共7個GPIO。也就是說,在同一時刻每個中斷線只能相應一個GPIO連接埠的中斷,不能夠同時相應所有連接埠的中斷事件,但是可以分時複用,在程式執行過程中,這個不需要我們太多的去關心。我們關心最多的是中斷觸發的方式

在EXTI中,有三種觸發中斷的方式:上升沿觸發,下降沿觸發,雙邊沿觸發。根據不同的電路,我們選擇不同的觸發方式,以確保中斷能夠被正常觸發。

執行個體

為了便於理解,這裡我們將中斷配置代碼貼上來。

void NVIC_Configuration(void){  NVIC_InitTypeDef NVIC_InitStructure;    /* 配置NVIC為優先順序組1 */  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);    /* 配置中斷源:按鍵1 */  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;  //配置為EXTI0通道  /* 配置搶佔優先順序 */  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  /* 配置子優先順序 */  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  /* 使能中斷通道 */  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  NVIC_Init(&NVIC_InitStructure); //將上述配置參數傳入中斷初始化函數}

除了中斷線的配置,我們還要配置對應引腳

void EXTI_Key_Config(void){    GPIO_InitTypeDef GPIO_InitStructure;     EXTI_InitTypeDef EXTI_InitStructure;    /*開啟按鍵GPIO口的時鐘*/    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);                                                    /* 配置 NVIC 中斷*/    NVIC_Configuration();/*--------------------------KEY1配置-----------------------------*/    /* 選擇按鍵用到的GPIO */     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  /* 配置為浮空輸入 */   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);    /* 選擇EXTI的訊號源 */  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);   EXTI_InitStructure.EXTI_Line = EXTI_Line0;        /* EXTI為中斷模式 */  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;    /* 上升沿中斷 */  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  /* 使能中斷 */      EXTI_InitStructure.EXTI_LineCmd = ENABLE;  EXTI_Init(&EXTI_InitStructure);}

至此,中斷的配置完畢。相信你已經看出來,上述代碼是將PA0配置為上升沿中斷。不過,現在只能夠說該中斷已經配置完畢,但我們還不能使用它。我們還缺少一個中斷的執行函數。

當中斷被觸發後,程式要馬上跳轉到中斷函數去執行中斷操作,這個函數在工程建立時預設時沒有的。需要你自己去添加。而且需要注意的是,中斷函數的名稱必須是由標準庫提供的,否則無法識別。

我們開啟startup_stm32f10x_hd.s這個檔案,在裡面能找到這麼一段代碼:

                ; External Interrupts                DCD     WWDG_IRQHandler            ; Window Watchdog                DCD     PVD_IRQHandler             ; PVD through EXTI Line detect                DCD     TAMPER_IRQHandler          ; Tamper                DCD     RTC_IRQHandler             ; RTC                DCD     FLASH_IRQHandler           ; Flash                DCD     RCC_IRQHandler             ; RCC                DCD     EXTI0_IRQHandler           ; EXTI Line 0                DCD     EXTI1_IRQHandler           ; EXTI Line 1                DCD     EXTI2_IRQHandler           ; EXTI Line 2                DCD     EXTI3_IRQHandler           ; EXTI Line 3                ...                ...                ...

不難看出,EXTI0_IRQHandler 就是中斷線0的中斷函數,所以,我們把這個函數添加到工程中即可。最好添加到stm32f10x_it.c 這個檔案中,方便管理。

可以在這個函數中添加你想要的功能,代碼如下:

void EXTI0_IRQHandler(void){  //確保是否產生了EXTI Line中斷    if(EXTI_GetITStatus(EXTI_Line0) != RESET)     {        /******/         //LED閃爍相關代碼        /******/    //清除中斷標誌位        EXTI_ClearITPendingBit(EXTI_Line0);         }  }

至此,整個中斷的流程梳理完畢,如果有什麼紕漏的話,歡迎探討!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.