新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > stm32_exti(含NVIC)配置及庫函數講解

        stm32_exti(含NVIC)配置及庫函數講解

        作者: 時間:2016-11-11 來源:網絡 收藏
        EXTIexternalinterrupt外部中斷

        STM32有76個中斷,包括16個內核中斷和60個可屏蔽中斷,具有16級可編程的中斷優先級。而我們常用的就是這60個可屏蔽中斷,所以我們就只針對這60個可屏蔽中斷進行介紹。

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

        關于中斷的設置,在STM32的PDF文檔中是找不到關于NVIC相關寄存器的說明的,是讓大家摸不著門道嗎?還是故裝高深?最后在《CM3權威指南》上找到NVIC相關寄存器,下面重點介紹這幾個寄存器。

        ISER[2]:ISER全稱是InterruptSet-EnableRegisters,這是一個中斷使能寄存器組。上面說了STM32的可屏蔽中斷只有60個,這里用了2個32位的寄存器,總共可以表示64個中斷。而STM32只用了其中的前60個。ISER[0]的bit0~bit31分別對應中斷0~31。ISER[1]的bit0~bit27對應中斷32~59;這樣總共60個中斷就分別對應上了。你要使能某個中斷,必須設置相應的ISER位為1,使該中斷被使能(這里僅僅是使能,還要配合中斷分組、屏蔽、IO口映射等設置才算是一個完整的中斷設置)。具體每一位對應哪個中斷,請參考stm32f10x_nvic.h里面的第36行處。

        /* IRQ Channels --------------------------------------------------------------*/
        #define WWDG_IRQChannel ((u8)0x00) /* Window WatchDog Interrupt */
        #define PVD_IRQChannel ((u8)0x01) /* PVD through EXTI Line detection Interrupt */
        #define TAMPER_IRQChannel ((u8)0x02) /* Tamper Interrupt */
        #define RTC_IRQChannel ((u8)0x03) /* RTC global Interrupt */
        #define FLASH_IRQChannel ((u8)0x04) /* FLASH global Interrupt */
        #define RCC_IRQChannel ((u8)0x05) /* RCC global Interrupt */
        #define EXTI0_IRQChannel ((u8)0x06) /* EXTI Line0 Interrupt */
        #define EXTI1_IRQChannel ((u8)0x07) /* EXTI Line1 Interrupt */
        #define EXTI2_IRQChannel ((u8)0x08) /* EXTI Line2 Interrupt */
        #define EXTI3_IRQChannel ((u8)0x09) /* EXTI Line3 Interrupt */
        #define EXTI4_IRQChannel ((u8)0x0A) /* EXTI Line4 Interrupt */
        #define DMA1_Channel1_IRQChannel ((u8)0x0B) /* DMA1 Channel 1 global Interrupt */
        #define DMA1_Channel2_IRQChannel ((u8)0x0C) /* DMA1 Channel 2 global Interrupt */
        #define DMA1_Channel3_IRQChannel ((u8)0x0D) /* DMA1 Channel 3 global Interrupt */
        #define DMA1_Channel4_IRQChannel ((u8)0x0E) /* DMA1 Channel 4 global Interrupt */
        #define DMA1_Channel5_IRQChannel ((u8)0x0F) /* DMA1 Channel 5 global Interrupt */
        #define DMA1_Channel6_IRQChannel ((u8)0x10) /* DMA1 Channel 6 global Interrupt */
        #define DMA1_Channel7_IRQChannel ((u8)0x11) /* DMA1 Channel 7 global Interrupt */
        #define ADC1_2_IRQChannel ((u8)0x12) /* ADC1 et ADC2 global Interrupt */
        #define USB_HP_CAN_TX_IRQChannel ((u8)0x13) /* USB High Priority or CAN TX Interrupts */
        #define USB_LP_CAN_RX0_IRQChannel ((u8)0x14) /* USB Low Priority or CAN RX0 Interrupts */
        #define CAN_RX1_IRQChannel ((u8)0x15) /* CAN RX1 Interrupt */
        #define CAN_SCE_IRQChannel ((u8)0x16) /* CAN SCE Interrupt */
        #define EXTI9_5_IRQChannel ((u8)0x17) /* External Line[9:5] Interrupts */
        #define TIM1_BRK_IRQChannel ((u8)0x18) /* TIM1 Break Interrupt */
        #define TIM1_UP_IRQChannel ((u8)0x19) /* TIM1 Update Interrupt */
        #define TIM1_TRG_COM_IRQChannel ((u8)0x1A) /* TIM1 Trigger and Commutation Interrupt */
        #define TIM1_CC_IRQChannel ((u8)0x1B) /* TIM1 Capture Compare Interrupt */
        #define TIM2_IRQChannel ((u8)0x1C) /* TIM2 global Interrupt */
        #define TIM3_IRQChannel ((u8)0x1D) /* TIM3 global Interrupt */
        #define TIM4_IRQChannel ((u8)0x1E) /* TIM4 global Interrupt */
        #define I2C1_EV_IRQChannel ((u8)0x1F) /* I2C1 Event Interrupt */
        #define I2C1_ER_IRQChannel ((u8)0x20) /* I2C1 Error Interrupt */
        #define I2C2_EV_IRQChannel ((u8)0x21) /* I2C2 Event Interrupt */
        #define I2C2_ER_IRQChannel ((u8)0x22) /* I2C2 Error Interrupt */
        #define SPI1_IRQChannel ((u8)0x23) /* SPI1 global Interrupt */
        #define SPI2_IRQChannel ((u8)0x24) /* SPI2 global Interrupt */
        #define USART1_IRQChannel ((u8)0x25) /* USART1 global Interrupt */
        #define USART2_IRQChannel ((u8)0x26) /* USART2 global Interrupt */
        #define USART3_IRQChannel ((u8)0x27) /* USART3 global Interrupt */
        #define EXTI15_10_IRQChannel ((u8)0x28) /* External Line[15:10] Interrupts */
        #define RTCAlarm_IRQChannel ((u8)0x29) /* RTC Alarm through EXTI Line Interrupt */
        #define USBWakeUp_IRQChannel ((u8)0x2A) /* USB WakeUp from suspend through EXTI Line Interrupt */
        #define TIM8_BRK_IRQChannel ((u8)0x2B) /* TIM8 Break Interrupt */
        #define TIM8_UP_IRQChannel ((u8)0x2C) /* TIM8 Update Interrupt */
        #define TIM8_TRG_COM_IRQChannel ((u8)0x2D) /* TIM8 Trigger and Commutation Interrupt */
        #define TIM8_CC_IRQChannel ((u8)0x2E) /* TIM8 Capture Compare Interrupt */
        #define ADC3_IRQChannel ((u8)0x2F) /* ADC3 global Interrupt */
        #define FSMC_IRQChannel ((u8)0x30) /* FSMC global Interrupt */
        #define SDIO_IRQChannel ((u8)0x31) /* SDIO global Interrupt */
        #define TIM5_IRQChannel ((u8)0x32) /* TIM5 global Interrupt */
        #define SPI3_IRQChannel ((u8)0x33) /* SPI3 global Interrupt */
        #define UART4_IRQChannel ((u8)0x34) /* UART4 global Interrupt */
        #define UART5_IRQChannel ((u8)0x35) /* UART5 global Interrupt */
        #define TIM6_IRQChannel ((u8)0x36) /* TIM6 global Interrupt */
        #define TIM7_IRQChannel ((u8)0x37) /* TIM7 global Interrupt */
        #define DMA2_Channel1_IRQChannel ((u8)0x38) /* DMA2 Channel 1 global Interrupt */
        #define DMA2_Channel2_IRQChannel ((u8)0x39) /* DMA2 Channel 2 global Interrupt */
        #define DMA2_Channel3_IRQChannel ((u8)0x3A) /* DMA2 Channel 3 global Interrupt */
        #define DMA2_Channel4_5_IRQChannel ((u8)0x3B) /* DMA2 Channel 4 and DMA2 Channel 5 global Interrupt */

        例如:EXTI9所對應的中斷號為23。

        ICER[2]:全稱是InterruptClear-EnableRegisters,是一個中斷除能寄存器組。該寄存器組與ISER的作用恰好相反,是用來清除某個中斷的使能的。這里要與專門設置一個ICER來清除中斷位,而不是向ISER寫0來清除,是因為NVIC的這些寄存器都是寫1有效的,寫0無效的。具體為什么這么設計,請看《CM3權威指南》第125頁。

        ISPR[2]:全稱是InterruptSet-PendingRegisters,是一個中斷掛起控制寄存器組。每一位對應的中斷和ISER是一樣的。通過置1,可以將正在進行的中斷掛起,而執行同級或更高級別的中斷。寫0是無效的。

        ICPR[2]:全稱是:InterruptClear-PendingRegisters,是一個中斷解掛控制寄存器組。其作用與ISPR相反,對應位也和ISER是一樣的。通過設置1,可以將掛起的中斷解掛。寫0無效。

        IABR[2]:全稱是ActiveBitRegisters,是一個中斷激活標志位寄存器組。對應位所代表的的中斷和ISER一樣,如果為1,則表示該位所對應的中斷正在被執行。這是一個只讀寄存器,通過它可以知道當前在執行的中斷是哪一個。在中斷執行完了由硬件自動清零。

        IPR[15]:全稱是InterruptPriorityRegisters,是一個中斷優先級控制的寄存器組。這個寄存器組相當重要!STM32的中斷分組與這個寄存器組密切相關。IPR寄存器組由15個32bit的寄存器組成,每個可屏蔽中斷占用8bit,這樣總共可以表示15*4=60個可屏蔽中斷。剛好和STM32的可屏蔽中斷數相等。IPR[0]的[31~24],[23~16],[15~8],[7~0]分別對應中斷3~0,以此類推,總共對應60個外部中斷。而每個可屏蔽中斷占用的8bit并沒有全部使用,而是只用了高4位。這4位,又分為搶占優先級和子優先級。搶占優先級在前,子優先級在后。而這兩個優先級各占幾個位又要根據SCB->AIRCR中中斷分組的設置來決定。

        這里簡單介紹一下STM32的中斷分組:STM32將中斷分為5各組,組0~4。該分組的設置是由SCB->AIRCR 寄存器的bit10~8來定義的。具體的分配關系如下表所示:

        例如:PB9對應中斷線EXTI9,NVIC_Priority Group=1,Preemption Priority=1,SubPriority=7,則IAR中的IP5的PRI_23=0xF0。

        stm32的固件庫中有兩個非常重要的結構體,如下

        /*------------------------ Nested Vectored Interrupt Controller --------------*/
        typedef struct
        {
        vu32 ISER[2]; //對應IAR中 SETENA0 和 SETENA1
        u32 RESERVED0[30];
        vu32 ICER[2]; //對應IAR中 CLRENA0 和 CLRENA1
        u32 RSERVED1[30];
        vu32 ISPR[2]; //對應IAR中 SETPEND0 和 SETPEND1
        u32 RESERVED2[30];
        vu32 ICPR[2]; //對應IAR中 CLRPEND0 和 CLRPEND1
        u32 RESERVED3[30];
        vu32 IABR[2]; //對應IAR中 ACTIVE0 和 ACTIVE1
        u32 RESERVED4[62];
        vu32 IPR[15]; //對應IAR中 IP0 到 IP15
        } NVIC_TypeDef;

        它們對應ARM手冊中的名稱為
        ISER=InterruptSet-EnableRegisters
        ICER=InterruptClear-EnableRegisters
        ISPR=InterruptSet-PendingRegister
        ICPR=InterruptClear-PendingRegister
        IABR=ActiveBitRegister
        IPR=InterruptPriorityRegisters

        typedef struct
        {
        vuc32 CPUID; //對應IAR中 CPUIDBR
        vu32 ICSR; //對應IAR中 ICSR
        vu32 VTOR; //對應IAR中 VTOR
        vu32 AIRCR; //對應IAR中 AIRCR
        vu32 SCR; //對應IAR中 SCR
        vu32 CCR; //對應IAR中 CCR
        vu32 SHPR[3]; //對應IAR中 SHPR0~SHPR2
        vu32 SHCSR; //對應IAR中 SHCSR
        vu32 CFSR; //對應IAR中 CFSR
        vu32 HFSR; //對應IAR中 HFSR
        vu32 DFSR; //對應IAR中 DFSR
        vu32 MMFAR; //對應IAR中 MMFAR
        vu32 BFAR; //對應IAR中 BFAR
        vu32 AFSR; //對應IAR中
        } SCB_TypeDef;

        它們對應ARM手冊中的名稱為

        CPUID=CPUIDBaseRegister
        ICSR=InterruptControlStateRegister
        VTOR=VectorTableOffsetRegister
        AIRCR=ApplicationInterrupt/ResetControlRegister
        SCR=SystemControlRegister
        CCR=ConfigurationControlRegister
        SHPR=SystemHandlersPriorityRegister
        SHCSR=SystemHandlerControlandStateRegister
        CFSR=ConfigurableFaultStatusRegisters
        HFSR=HardFaultStatusRegister
        DFSR=DebugFaultStatusRegister
        MMFAR=MemManageAddressRegister
        BFAR=BusFaultAddressRegister
        AFSR=AuxiliaryFaultStatusRegister

        UserButton硬件連接如下圖所示:當按鍵被按下,PB9檢測到低電平,相反PB9被3.3V電源拉高。

        LED硬件連接如下圖所示:高電平點亮LED。

        本實驗要實現的功能是:按User鍵,用中斷的方式點亮LED1。

        預備知識:80個通用I/O端口以下圖的方式連接到19個外部中斷/事件線上:

        另外三種其他的外部中斷/事件控制器的連接如下:

        EXTI16 連接到PVD輸出

        EXTI17 連接到RTC鬧鐘事件

        EXTI18 連接到USB喚醒事件


        涉及到AFIO_EXTICR1~AFIO_EXTICR4寄存器,如下所示

        由上圖可知:PB9連接到EXTI9上。

        第一步:配置系統時鐘。見STM32F103xRCC寄存器配置

        /* Enable GPIOC and GPIOB clock */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

        /* Enable AFIO clock */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

        注意:別忘了將AFIO時鐘打開。

        第二步:配置中斷向量表。本章重點!

        void NVIC_Configuration(void)
        {
        NVIC_InitTypeDef NVIC_InitStructure;

        #ifdef VECT_TAB_RAM
        /* Set the Vector Table base location at 0x20000000 */
        NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
        #else /* VECT_TAB_FLASH */
        /* Set the Vector Table base location at 0x08000000 */
        NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
        #endif

        /* Configure one bit for preemption priority */
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

        /* Enable the EXTI9_5 Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        }

        該函數完成兩個功能

        1.決定將程序下載到RAM中還是FLASH中

        2.配置中斷分組。(NVIC中斷分組只能設置一次)

        3.選擇中斷通道號,搶占式優先級和響應優先級,使能中斷

        第三步:配置GPIO的模式。輸入模式還是輸出模式。點亮LED已講過。

        void GPIO_Configuration(void)
        {
        GPIO_InitTypeDef GPIO_InitStructure;

        /* Configure PC.06 as Output push-pull */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOC, &GPIO_InitStructure);

        /* Configure PB.09 as input floating (EXTI Line 9) */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //輸入懸空模式
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        }


        第四步:外部中斷線配置,本章重點!

        void EXTI_Configuration(void)
        {
        EXTI_InitTypeDef EXTI_InitStructure;

        /* Connect EXTI Line9 to PB.09 */
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource9);

        /* Configure EXTI Line9 to generate an interrupt on falling edge */
        EXTI_InitStructure.EXTI_Line = 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);
        }

        該函數完成兩個功能

        1.將PB9管腳用作外部中斷

        2.選擇中斷線,中斷模式(中斷還是事件),觸發模式(電平還是跳變沿),使能

        exti.c文件完整代碼如下:

        /* Includes ------------------------------------------------------------------*/
        #include "stm32f10x_lib.h"

        /* Private function prototypes -----------------------------------------------*/
        void RCC_Configuration(void);
        void NVIC_Configuration(void);
        void GPIO_Configuration(void);
        void EXTI_Configuration(void);
        void Delay(vu32 nCount);

        /*******************************************************************************
        * Function Name : main
        * Description : Main program.
        * Input : None
        * Return : None
        *******************************************************************************/
        int main(void)
        {
        #ifdef DEBUG
        debug();
        #endif

        /* Configure the system clocks */
        RCC_Configuration();

        /* NVIC Configuration */
        NVIC_Configuration();

        /* Configure the GPIO ports */
        GPIO_Configuration();

        /* Configure the EXTILine */
        EXTI_Configuration();

        /* Generate software interrupt: simulate a falling edge applied on EXTI line 9 */
        EXTI_GenerateSWInterrupt(EXTI_Line9); //只能產生一次

        /* Infinite loop */
        while (1)
        {
        }
        }

        /*******************************************************************************
        * Function Name : RCC_Configuration
        * Description : Configures the different system clocks.
        * Input : None
        * Return : None
        *******************************************************************************/
        void RCC_Configuration(void)
        {
        ErrorStatus HSEStartUpStatus;

        /* RCC system reset(for debug purpose) */
        RCC_DeInit();

        /* Enable HSE */
        RCC_HSEConfig(RCC_HSE_ON);

        /* Wait till HSE is ready */
        HSEStartUpStatus = RCC_WaitForHSEStartUp();

        if (HSEStartUpStatus == SUCCESS)
        {
        /* Enable Prefetch Buffer */
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

        /* Flash 2 wait state */
        FLASH_SetLatency(FLASH_Latency_2);

        /* HCLK = SYSCLK */
        RCC_HCLKConfig(RCC_SYSCLK_Div1);

        /* PCLK2 = HCLK */
        RCC_PCLK2Config(RCC_HCLK_Div1);

        /* PCLK1 = HCLK/2 */
        RCC_PCLK1Config(RCC_HCLK_Div2);

        /* PLLCLK = 8MHz * 9 = 72 MHz */
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

        /* Enable PLL */
        RCC_PLLCmd(ENABLE);

        /* Wait till PLL is ready */
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}

        /* Select PLL as system clock source */
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

        /* Wait till PLL is used as system clock source */
        while(RCC_GetSYSCLKSource() != 0x08) {}
        }

        /* Enable GPIOC and GPIOB clock */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

        /* Enable AFIO clock */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
        }

        /*******************************************************************************
        * Function Name : NVIC_Configuration
        * Description : Configures Vector Table base location.
        * Input : None
        * Return : None
        *******************************************************************************/
        void NVIC_Configuration(void)
        {
        NVIC_InitTypeDef NVIC_InitStructure;

        #ifdef VECT_TAB_RAM
        /* Set the Vector Table base location at 0x20000000 */
        NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
        #else /* VECT_TAB_FLASH */
        /* Set the Vector Table base location at 0x08000000 */
        NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
        #endif

        /* Configure one bit for preemption priority */
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

        /* Enable the EXTI9_5 Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        }

        /*******************************************************************************
        * Function Name : GPIO_Configuration
        * Description : Configures the different GPIO ports.
        * Input : None
        * Return : None
        *******************************************************************************/
        void GPIO_Configuration(void)
        {
        GPIO_InitTypeDef GPIO_InitStructure;

        /* Configure PC.06 as Output push-pull */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOC, &GPIO_InitStructure);

        /* Configure PB.09 as input floating (EXTI Line 9) */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //輸入懸空模式
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        }

        /*******************************************************************************
        * Function Name : EXTI_Configuration
        * Description : Configures the EXTILine.
        * Input : None
        * Return : None
        *******************************************************************************/
        void EXTI_Configuration(void)
        {
        EXTI_InitTypeDef EXTI_InitStructure;

        /* Connect EXTI Line9 to PB.09 */
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource9);

        /* Configure EXTI Line9 to generate an interrupt on falling edge */
        EXTI_InitStructure.EXTI_Line = 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);
        }

        /*******************************************************************************
        * Function Name : Delay
        * Description : Inserts a delay time.
        * Input : nCount: specifies the delay time length.
        * Return : None
        *******************************************************************************/
        void Delay(vu32 nCount)
        {
        for(; nCount != 0; nCount--);
        }

        #ifdef DEBUG
        /*******************************************************************************
        * Function Name : assert_failed
        * Description : Reports the name of the source file and the source line number
        * where the assert_param error has occurred.
        * Input : - file: pointer to the source file name
        * - line: assert_param error line source number
        * Return : None
        *******************************************************************************/
        void assert_failed(u8* file, u32 line)
        {
        /* User can add his own implementation to report the file name and line number,
        ex: printf("Wrong parameters value: file %s on line %drn", file, line) */

        /* Infinite loop */
        while (1)
        {
        }
        }
        #endif


        stm32f10x_it.c有關EXTI9代碼如下

        void EXTI9_5_IRQHandler(void)
        {
        if (EXTI_GetITStatus(EXTI_Line9) != RESET)
        {
        /* Toggle PC6 pin */
        GPIO_WriteBit(GPIOC, GPIO_Pin_6, (BitAction)((1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_6))));

        /* Clear the EXTI line 9 pending bit */
        EXTI_ClearITPendingBit(EXTI_Line9);
        }
        }

        最后,需要提示一下,添加工程文件時一定別忘了將stm32f10x_vector.c文件加到project中,否則中斷進入FaultISR。具體方法見



        關鍵詞: stm32NVIC庫函

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 兴仁县| 玉林市| 孝昌县| 花莲县| 银川市| 永州市| 白城市| 民和| 台安县| 蒲城县| 乐东| 静乐县| 洞头县| 石渠县| 筠连县| 体育| 开鲁县| 张北县| 微博| 育儿| 昌宁县| 鹤庆县| 百色市| 揭阳市| 磐石市| 游戏| 玛沁县| 平果县| 利辛县| 宜兰县| 天全县| 宝山区| 海晏县| 济南市| 石泉县| 乌拉特中旗| 东港市| 巴东县| 金沙县| 辛集市| 新余市|