STM32學習筆記——中斷

菠菜面筋發表於2024-09-11

中斷:在主程式執行過程中,出現了特定事件(例如發生已經預知的一些情況),從而轉入中斷程式中,處理完成後再回到主程式中繼續執行。(頻繁的中斷函式會影響主程式的執行,所以中斷函式一邊不處理特別複雜的邏輯)

EXTI(Extern Interrupt)外部中斷

支援的觸發方式:上升沿/下降沿/雙邊沿/軟體觸發

支援的GPIO口:所有GPIO口,但相同的Pin不能同時觸發中斷

通道數:16個GPIO_Pin,外加PVD輸出、RTC鬧鐘、USB喚醒、乙太網喚醒(0-15:對應GPIO_PIN 0-15中斷;16:PVD輸出;17:RTC鬧鐘事件;18:USB喚醒事件;19:連線到乙太網喚醒事件(只適用於互聯型產品))

觸發響應方式:中斷響應/事件響應

注意EXTI9_5和EXTI15_10這幾個中斷在兩個通道里,需要透過標誌位判斷。

EXTI中斷髮生流程:EXTI監測指定GPIO口的電平訊號,當其指定的GPIO口產生電平變化時,EXTI將立即向NVIC發出中斷申請,經過NVIC裁決後即可中斷CPU主程式,使CPU執行EXTI對應的中斷程式。

NVIC(Nested vectoredinterrupt controller)巢狀向量中斷控制器

NVIC提供了靈活、高效、可擴充套件的中斷處理機制,支援多級優先順序、多向中斷、巢狀向量中斷等特性。

NVIC支援多級優先順序,可以配置不同的優先順序和互斥優先順序組。中斷控制器負責中斷的掛起、解掛和優先順序管理。

透過檢測GPIO的PB14的電平變化觸發中斷的例項:

初始化:

void EXTI_NVIC_Init(void){
    /* GPIO --> AFIO */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);    //開啟GPIOB口時鐘,因為檢測的是PB14口的電平訊號
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);        //開啟AFIO時鐘
    GPIO_InitTypeDef GPIO_InitStructure;                    //初始化PB14引腳
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
    /* AFIO -->  EXTI */
    EXTI_InitTypeDef EXTI_InitStructure;                    //初始化EXTI
    EXTI_InitStructure.EXTI_Line =EXTI_Line14;                //選擇14號線
    EXTI_InitStructure.EXTI_LineCmd =ENABLE;                //14號線使能
    EXTI_InitStructure.EXTI_Mode =EXTI_Mode_Interrupt;        //選擇模式,這裡是中斷模式觸發中斷,如果是EXTI_Mode_Event,就是觸發一個事件
    EXTI_InitStructure.EXTI_Trigger =EXTI_Trigger_Falling; //觸發方式:EXTI_Trigger_Falling ,EXTI_Trigger_Rising_Falling ,EXTI_Trigger_Rising,這裡選的是下降沿觸發
    EXTI_Init(&EXTI_InitStructure);
    /* EXTI -->  NVIC */                                    //開啟NVIC
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);            //設定優先分組為2,這裡是隨便設定的
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = 40;                    //EXTI15_10_IRQn=40, /*!< External Line[15:10] Interrupts */ 選擇配置EXTI15_10線這裡PB14在EXTI15_10中
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;            //線路使能
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;    //搶佔優先順序
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;            //響應優先順序
    NVIC_Init(&NVIC_InitStruct);                            //初始化
}

中斷函式:

void EXTI15_10_IRQHandler(void){                    //函式名為預留的指定名稱,可以從啟動檔案複製
    //中斷標誌位判斷
    if(EXTI_GetITStatus(EXTI_Line14) == SET){        //判斷是否是14號線觸發的中斷
        /*可新增一些操作
        *count++;
        */
        EXTI_ClearITPendingBit(EXTI_Line14);//清除中斷標誌
    }
}

相關文章