新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32單片機學習(2) 外部中斷

        STM32單片機學習(2) 外部中斷

        作者: 時間:2016-11-20 來源:網絡 收藏
        李想stm32視頻教程49集http://pan.baidu.com/s/1kTyt03PSTM32的中斷(上中下)外部中斷(寄存器、庫函數)

        STM32的函數說明(中文).pdf http://download.csdn.net/detail/leytton/7630851
        中?斷?管?理?函?數.pdf http://wenku.baidu.com/view/b90e5b82360cba1aa811dad3.html

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

        概念基礎

        STM32共76個中斷,16個內核中斷,60個外部中斷,即可屏蔽中斷

        中斷分5組:0-4,所有中斷只能放在同一組里

        ISER[0]、ISER[1]是32位的中斷使能寄存器數組,ISER[0]的bit0-31對應中斷0-31、ISER[1]的bit0-27對應中斷32-59,置1有效
        ICER[0]、ICER[1]正好相反,是清除使能,置1有效

        stm32中斷搶占優先級和響應優先級有什么區別?
        中斷A搶占優先級比B高,那么A的中斷可以在B里面觸發,忽略響應優先級;
        A和B搶占優先級相同,則A、B的響應優先級決定誰先響應;
        搶占優先級高的可以打斷搶占優先級低的中斷,響應式則不能
        數字越小,優先級越高

        中斷配置步驟


        源代碼

        /**	* 軟件功能:	 中斷閃燈實驗(軟件延時方式) 按鍵中斷* */#include "stm32f10x.h"#include #include "delay.h"void RCC_Configuration(void);void GPIO_Configuration(void);void NVIC_Configuration(void);void EXTI_Configuration(void);/*函數: int main(void)功能: main主函數參數: 無返回: 無/int main(void){RCC_Configuration();GPIO_Configuration();delay_init(72);NVIC_Configuration();EXTI_Configuration();GPIO_ResetBits(GPIOA,GPIO_Pin_0);//滅	  GPIO_ResetBits(GPIOA,GPIO_Pin_2);//滅while(1);}/*函數: void RCC_Configuration(void)功能: 復位和時鐘控制 配置參數: 無返回: 無/void RCC_Configuration(void){ErrorStatus HSEStartUpStatus;                    //定義外部高速晶體啟動狀態枚舉變量RCC_DeInit();                                    //復位RCC外部設備寄存器到默認值RCC_HSEConfig(RCC_HSE_ON);                       //打開外部高速晶振HSEStartUpStatus = RCC_WaitForHSEStartUp();      //等待外部高速時鐘準備好if(HSEStartUpStatus == SUCCESS)                  //外部高速時鐘已經準別好{FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //開啟FLASH預讀緩沖功能,加速FLASH的讀取。所有程序中必須的用法.位置:RCC初始化子函數里面,時鐘起振之后FLASH_SetLatency(FLASH_Latency_2);                    //flash操作的延時RCC_HCLKConfig(RCC_SYSCLK_Div1);               //配置AHB(HCLK)時鐘等于==SYSCLKRCC_PCLK2Config(RCC_HCLK_Div1);                //配置APB2(PCLK2)鐘==AHB時鐘RCC_PCLK1Config(RCC_HCLK_Div2);                //配置APB1(PCLK1)鐘==AHB1/2時鐘RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  //配置PLL時鐘 == 外部高速晶體時鐘 * 9 = 72MHzRCC_PLLCmd(ENABLE);                                   //使能PLL時鐘while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)    //等待PLL時鐘就緒{}RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);            //配置系統時鐘 = PLL時鐘while(RCC_GetSYSCLKSource() != 0x08)                  //檢查PLL時鐘是否作為系統時鐘{}}RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);  //允許 GPIOB、AFIO時鐘}/*函數: void GPIO_Configuration(void)功能: GPIO配置參數: 無返回: 無/void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;        //定義GPIO初始化結構體GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); 	   //PA用于輸出控制LED燈GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //上拉輸入GPIO_Init(GPIOB, &GPIO_InitStructure); 	   //PB.0用于接受按鍵k1輸入}void NVIC_Configuration(void)	 //中斷分組和優先級配置	 詳見《STM32的函數說明(中文).pdf》P165{NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);	 //0組,先占優先級0位,從優先級4位NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //外部中斷線 0 中斷NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 	  //0組無搶占優先級,所以只配置從優先級,即響應式優先級NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能NVIC_Init(& NVIC_InitStructure); //初始化配置}void EXTI_Configuration(void)  //中斷配置  //詳見《STM32的函數說明(中文).pdf》	  P99{EXTI_InitTypeDef EXTI_InitStructure;		EXTI_ClearITPendingBit(EXTI_Line0);//清除 EXTI 線路掛起位EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //設置 EXTI 線路為中斷請求EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //設置輸入線路下降沿為中斷請求EXTI_InitStructure.EXTI_Line = EXTI_Line0; //外部中斷線 0EXTI_InitStructure.EXTI_LineCmd	= ENABLE;//使能EXTI_Init(& EXTI_InitStructure); //初始化配置GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);	 ///*將EXTI線0連接到PB0*/}/*中斷服務程序*/void EXTI0_IRQHandler()	  //按下按鈕還是放開按鈕是下降沿??{if(EXTI_GetITStatus(EXTI_Line0) == SET)//檢查指定的EXTI線路觸發請求發生與否,返回一個EXTI_Line新狀態{EXTI_ClearITPendingBit(EXTI_Line0);//清除線路掛起位EXTI_ClearFlag(EXTI_Line0);//清除中斷掛起位 GPIO_SetBits(GPIOA,GPIO_Pin_0);//點亮LED                delay_ms(500);//延時GPIO_ResetBits(GPIOA,GPIO_Pin_0);//滅if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0))  GPIO_SetBits(GPIOA,GPIO_Pin_2);//點亮LEDelse  GPIO_ResetBits(GPIOA,GPIO_Pin_2);//滅} }

        可另行參考文章:

        STM32學習筆記之EXTI(外部中斷)http://blog.sina.com.cn/s/blog_6623834301018woa.html

        參考資料:STM32數據手冊、網絡資料

        ==================================================================================

        外部中斷/事件控制器由19個產生事件/中斷要求的邊沿檢測器組成。每個輸入線可以獨立地配置

        輸入類型(脈沖或掛起)和對應的觸發事件(上升沿或下降沿或者雙邊沿都觸發)。每個輸入線都可以被獨

        立的屏蔽。掛起寄存器保持著狀態線的中斷要求。

        ==================================================================================

        19個中斷如下:

        17——EXTI線16連接到PVD輸出

        18——EXTI線17連接到RTC鬧鐘事件

        19——EXTI線18連接到USB喚醒事件

        注:有上圖可知EXTI0連接的引腳為PA0、PB0、PC0、PD0、PE0、PF0、PG0,其他外部中斷EXTI1——

        EXTI15類似。所以在使用時盡量將需要的外部中斷配置在不同的EXTIx上。

        例如需要3個外部中斷,我們可以配置到PA0、PB4、PG3上,此時每個中斷都有自己的中斷處理程

        序段。如果配置到PA0、PB0、PC1,則PA0和PB0將公用一個中斷程序段。當然如果特殊需要,也

        可以這樣設計。

        ==================================================================================

        配置使用方法:

        1. 初始化相應的GPIO管腳
        2. 配置外部中斷源并進行中斷源和GPIO的連接
        3. 編寫相應中斷源的中斷處理程序

        ==================================================================================

        程序代碼

        • 初始化相應的GPIO管腳

        GPIO_InitTypeDef GPIO_InitStructure;


        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);


        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOE, &GPIO_InitStructure);


        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);

        注:GPIO的復用功能必須打開,如紅字部分

        • 配置外部中斷源并進行中斷源和GPIO的連接


        GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource0);
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource1);
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource8);
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource9);


        EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line1|EXTI_Line8|EXTI_Line9;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);

        • 編寫相應中斷源的中斷處理程序


        void EXTI0_IRQHandler(void)
        {
        if(Sys_Status > MIN_STATUS)
        {
        Sys_Status --;
        }
        EXTI_ClearITPendingBit(EXTI_Line0);
        }


        void EXTI1_IRQHandler(void)
        {
        PEout(2) = ~PEout(2);
        EXTI_ClearITPendingBit(EXTI_Line1);
        }


        #define Exti_From_Pin8 0x00000100
        #define Exti_From_Pin9 0x00000200

        void EXTI9_5_IRQHandler(void)
        {

        u32 Temp = 0x00;

        PEout(2) = ~PEout(2);
        Temp = EXTI->PR; //取讀是那個引腳的中斷
        switch(Temp)
        {
        case Exti_From_Pin8:
        EXTI_ClearITPendingBit(EXTI_Line8);
        break;
        case Exti_From_Pin9:
        if(Sys_Status < MAX_STATUS)
        {
        Sys_Status ++;
        }
        EXTI_ClearITPendingBit(EXTI_Line9);
        break;
        default:break;
        }
        }

        ==================================================================================

        中斷處理程序說明,由于外部中斷EXTI5——EXTI9公用了一個中斷(EXTI10——EXTI15類似)所以要

        區分不同的中斷源需要進行相應的判斷。如上EXTI9_5_IRQHandler中,通過取讀EXTI->PR寄存器來判

        斷中斷的來源。



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 广宗县| 连州市| 曲靖市| 萨迦县| 沾益县| 扬州市| 忻城县| 响水县| 易门县| 沙雅县| 乐清市| 如皋市| 舞阳县| 民县| 安福县| 乃东县| 岑溪市| 清丰县| 仙居县| 平潭县| 太谷县| 西藏| 雷波县| 宜都市| 泰兴市| 德阳市| 丹阳市| 独山县| 桐庐县| 乡城县| 密云县| 宜章县| 延边| 镇江市| 长岛县| 璧山县| 聂荣县| 宁陕县| 保定市| 肃北| 湘西|