STM32外部中断方式按键操作(STM32_09)

一、中断配置的步骤

1、使能中断

2、设置中断优先级分组

void NVIC_PriorityGroupConfig(uint32_tNVIC_PriorityGroup);

#define NVIC_PriorityGroup_0         ((uint32_t)0x700) /*0位抢占,4位响应 */

#define NVIC_PriorityGroup_1         ((uint32_t)0x600) /*1位抢占,3位响应 */

#define NVIC_PriorityGroup_2         ((uint32_t)0x500) /*2位抢占,2位响应 */

#define NVIC_PriorityGroup_3         ((uint32_t)0x400) /*3位抢占,1位响应 */

#define NVIC_PriorityGroup_4         ((uint32_t)0x300) /*4位抢占,0位响应 */

    一般选择NVIC_PriorityGroup_2,即抢占和响应均有4级。

3、配置NVIC_InitTypeDef结构体

void NVIC_Init(NVIC_InitTypeDef*NVIC_InitStruct);

typedef struct

{

  uint8_t NVIC_IRQChannel;   /*指定要使能或要失能的IRQ通道,这个值可以从stm32f10x.h中引用*/

  uint8_t NVIC_IRQChannelPreemptionPriority;  /*指定抢占优先级,0-15 */

  uint8_t NVIC_IRQChannelSubPriority;        /*指定响应优先级,0-15 */

  FunctionalState NVIC_IRQChannelCmd;     /*使能或失能 ENABLE / DISABLE */  

} NVIC_InitTypeDef;

NVIC_IRQChannelPreemptionPriority和NVIC_IRQChannelSubPriority的取值范围与调用中断优先级分组函数NVIC_PriorityGroupConfig时的配置相关,如果分组选择的是NVIC_PriorityGroup_2,则这两个的取值均为0-3。

stm32f10x.h中定义的中断通道值(HD):

typedef enum IRQn

{

/******  Cortex-M3 Processor Exceptions Numbers ************/

  NonMaskableInt_IRQn         = -14,    /*!< 2 Non Maskable Interrupt                         */

  MemoryManagement_IRQn       = -12,    /*!< 4 Cortex-M3 Memory Management Interrupt        */

  BusFault_IRQn               = -11,    /*!< 5 Cortex-M3 Bus Fault Interrupt                    */

  UsageFault_IRQn             = -10,    /*!< 6 Cortex-M3 Usage Fault Interrupt                  */

  SVCall_IRQn                 = -5,     /*!< 11 Cortex-M3 SV Call Interrupt                    */

  DebugMonitor_IRQn           = -4,     /*!< 12 Cortex-M3 Debug Monitor Interrupt              */

  PendSV_IRQn                 = -2,     /*!< 14 Cortex-M3 Pend SV Interrupt                   */

  SysTick_IRQn                = -1,     /*!< 15 Cortex-M3 System Tick Interrupt                 */

/******  STM32 specific Interrupt Numbers ***********************************/

  WWDG_IRQn                   = 0,      /*!< Window WatchDog Interrupt                   */

  PVD_IRQn                    = 1,      /*!< PVD through EXTI Line detection Interrupt         */

  TAMPER_IRQn                 = 2,      /*!< Tamper Interrupt                             */

  RTC_IRQn                    = 3,      /*!< RTC global Interrupt                            */

  FLASH_IRQn                  = 4,      /*!< FLASH global Interrupt                        */

  RCC_IRQn                    = 5,      /*!< RCC global Interrupt                           */

  EXTI0_IRQn                  = 6,      /*!< EXTI Line0 Interrupt                           */

  EXTI1_IRQn                  = 7,      /*!< EXTI Line1 Interrupt                           */

  EXTI2_IRQn                  = 8,      /*!< EXTI Line2 Interrupt                           */

  EXTI3_IRQn                  = 9,      /*!< EXTI Line3 Interrupt                           */

  EXTI4_IRQn                  = 10,     /*!< EXTI Line4 Interrupt                           */

  DMA1_Channel1_IRQn          = 11,     /*!< DMA1 Channel 1 global Interrupt                */

  DMA1_Channel2_IRQn          = 12,     /*!< DMA1 Channel 2 global Interrupt                 */

  DMA1_Channel3_IRQn          = 13,     /*!< DMA1 Channel 3 global Interrupt                 */

  DMA1_Channel4_IRQn          = 14,     /*!< DMA1 Channel 4 global Interrupt                 */

  DMA1_Channel5_IRQn          = 15,     /*!< DMA1 Channel 5 global Interrupt                 */

  DMA1_Channel6_IRQn          = 16,     /*!< DMA1 Channel 6 global Interrupt                 */

  DMA1_Channel7_IRQn          = 17,     /*!< DMA1 Channel 7 global Interrupt                 */

#ifdef STM32F10X_HD

  ADC1_2_IRQn             = 18,   /* ADC1 and ADC2 global Interrupt                  */

  USB_HP_CAN1_TX_IRQn   = 19, /* USB Device High Priority or CAN1 TX Interrupts       */

  USB_LP_CAN1_RX0_IRQn  = 20,     /* USB Device Low Priority or CAN1 RX0 Interrupts  */

  CAN1_RX1_IRQn          = 21, /* CAN1 RX1 Interrupt                               */

  CAN1_SCE_IRQn          = 22,/* CAN1 SCE Interrupt                                */

  EXTI9_5_IRQn             = 23,     /* External Line[9:5] Interrupts                    */

  TIM1_BRK_IRQn          = 24,     /* TIM1 Break Interrupt                           */

  TIM1_UP_IRQn            = 25,     /* TIM1 Update Interrupt                         */

  TIM1_TRG_COM_IRQn     = 26,     /* TIM1 Trigger and Commutation Interrupt          */

  TIM1_CC_IRQn            = 27,     /* TIM1 Capture Compare Interrupt                 */

  TIM2_IRQn                = 28,     /* TIM2 global Interrupt                          */

  TIM3_IRQn                = 29,     /* TIM3 global Interrupt                          */

  TIM4_IRQn                = 30,     /* TIM4 global Interrupt                           */

  I2C1_EV_IRQn             = 31,     /* I2C1 Event Interrupt                            */

  I2C1_ER_IRQn             = 32,     /* I2C1 Error Interrupt                             */

  I2C2_EV_IRQn             = 33,     /* I2C2 Event Interrupt                             */

  I2C2_ER_IRQn             = 34,     /* I2C2 Error Interrupt                             */

  SPI1_IRQn                = 35,     /* SPI1 global Interrupt                             */

  SPI2_IRQn                = 36,     /* SPI2 global Interrupt                             */

  USART1_IRQn             = 37,     /* USART1 global Interrupt                         */

  USART2_IRQn             = 38,     /* USART2 global Interrupt                         */

  USART3_IRQn             = 39,     /* USART3 global Interrupt                         */

  EXTI15_10_IRQn           = 40,     /* External Line[15:10] Interrupts                    */

  RTCAlarm_IRQn            = 41,     /* RTC Alarm through EXTI Line Interrupt             */

  USBWakeUp_IRQn          = 42,   /* USB Device WakeUp from suspend through EXTI Line Interrupt */

  TIM8_BRK_IRQn           = 43,     /* TIM8 Break Interrupt                          */

  TIM8_UP_IRQn             = 44,     /* TIM8 Update Interrupt                          */

  TIM8_TRG_COM_IRQn      = 45,     /* TIM8 Trigger and Commutation Interrupt         */

  TIM8_CC_IRQn             = 46,     /* TIM8 Capture Compare Interrupt                  */

  ADC3_IRQn                = 47,     /* ADC3 global Interrupt                          */

  FSMC_IRQn                = 48,     /* FSMC global Interrupt                           */

  SDIO_IRQn                 = 49,     /* SDIO global Interrupt                            */

  TIM5_IRQn                 = 50,     /* TIM5 global Interrupt                            */

  SPI3_IRQn                  = 51,     /* SPI3 global Interrupt                             */

  UART4_IRQn                = 52,     /* UART4 global Interrupt                          */

  UART5_IRQn                = 53,     /* UART5 global Interrupt                          */

  TIM6_IRQn                  = 54,     /* TIM6 global Interrupt                            */

  TIM7_IRQn                  = 55,     /* TIM7 global Interrupt                             */

  DMA2_Channel1_IRQn        = 56,     /* DMA2 Channel 1 global Interrupt                  */

  DMA2_Channel2_IRQn        = 57,     /* DMA2 Channel 2 global Interrupt                  */

  DMA2_Channel3_IRQn        = 58,     /* DMA2 Channel 3 global Interrupt                  */

  DMA2_Channel4_5_IRQn      = 59      /* DMA2 Channel 4 and Channel 5 global Interrupt     */

} IRQn_Type;

4、编写中断服务函数

中断服务函数有固定的函数名,在startup_stm32f10x_hd.s文件中已经定义:

__Vectors       DCD     __initial_sp               ; Top of Stack

                DCD     Reset_Handler              ; Reset Handler

                DCD     NMI_Handler                ; NMI Handler

                DCD     HardFault_Handler          ; Hard Fault Handler

                DCD     MemManage_Handler          ; MPU Fault Handler

                DCD     BusFault_Handler           ; Bus Fault Handler

                DCD     UsageFault_Handler         ; Usage Fault Handler

                DCD     0                          ; Reserved

                DCD     0                          ; Reserved

                DCD     0                          ; Reserved

                DCD     0                          ; Reserved

                DCD     SVC_Handler                ; SVCall Handler

                DCD     DebugMon_Handler           ; Debug Monitor Handler

                DCD     0                          ; Reserved

                DCD     PendSV_Handler             ; PendSV Handler

                DCD     SysTick_Handler            ; SysTick Handler

                ; 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

                DCD     EXTI4_IRQHandler           ; EXTI Line 4

                DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1

                DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2

                DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3

                DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4

                DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5

                DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6

                DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7

                DCD     ADC1_2_IRQHandler          ; ADC1 & ADC2

                DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX

                DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0

                DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1

                DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE

                DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5

                DCD     TIM1_BRK_IRQHandler        ; TIM1 Break

                DCD     TIM1_UP_IRQHandler         ; TIM1 Update

                DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation

                DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare

                DCD     TIM2_IRQHandler            ; TIM2

                DCD     TIM3_IRQHandler            ; TIM3

                DCD     TIM4_IRQHandler            ; TIM4

                DCD     I2C1_EV_IRQHandler         ; I2C1 Event

                DCD     I2C1_ER_IRQHandler         ; I2C1 Error

                DCD     I2C2_EV_IRQHandler         ; I2C2 Event

                DCD     I2C2_ER_IRQHandler         ; I2C2 Error

                DCD     SPI1_IRQHandler            ; SPI1

                DCD     SPI2_IRQHandler            ; SPI2

                DCD     USART1_IRQHandler          ; USART1

                DCD     USART2_IRQHandler          ; USART2

                DCD     USART3_IRQHandler          ; USART3

                DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10

                DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI Line

                DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend

                DCD     TIM8_BRK_IRQHandler        ; TIM8 Break

                DCD     TIM8_UP_IRQHandler         ; TIM8 Update

                DCD     TIM8_TRG_COM_IRQHandler    ; TIM8 Trigger and Commutation

                DCD     TIM8_CC_IRQHandler         ; TIM8 Capture Compare

                DCD     ADC3_IRQHandler            ; ADC3

                DCD     FSMC_IRQHandler            ; FSMC

                DCD     SDIO_IRQHandler            ; SDIO

                DCD     TIM5_IRQHandler            ; TIM5

                DCD     SPI3_IRQHandler            ; SPI3

                DCD     UART4_IRQHandler           ; UART4

                DCD     UART5_IRQHandler           ; UART5

                DCD     TIM6_IRQHandler            ; TIM6

                DCD     TIM7_IRQHandler            ; TIM7

                DCD     DMA2_Channel1_IRQHandler   ; DMA2 Channel1

                DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2

                DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3

                DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5

__Vectors_End

二、外部中断/事件控制器EXTI

互联网型产品有20个EXTI,其他的有19个,与IO口引脚相连的有16个(EXTI0-EXTI15),还有PVD(EXTI线16),RTCAlarm(EXTI线17),USB唤醒(EXTI线18),以及互联网型的ETH_WKUP(EXTI线19)。EXTI0~EXTI15可以被映射到GPIOA-GPIOG的引脚上。

EXTI结构框图

三、外部中断配置

配置外部中断使用STM32外设库函数,涉及"stm32f10x_exti.h"、"stm32f10x_exti.c"、"stm32f10x_gpio.h"和"stm32f10x_gpio.c"四个文件。

在本程序中将开发板上的四个按键均配置为外部中断源,分别是GPIOA_0对应EXTI_Line0,GPIOE_2、GPIOE_3、和GPIOE_4分别对应EXTI_2、EXTI_3和EXTI_4。

1、使能IO口时钟,配置IO口为输入模式

2、开启AFIO时钟

RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE );

3、设置IO口与中断线的映射关系

使用GPIO_EXTILineConfig函数("stm32f10x_gpio.h"和"stm32f10x_gpio.c")该函数原型为:void GPIO_EXTILineConfig( uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

其中GPIO_PortSource取值如下:

#define GPIO_PortSourceGPIOA       ((uint8_t)0x00)

#define GPIO_PortSourceGPIOB       ((uint8_t)0x01)

#define GPIO_PortSourceGPIOC       ((uint8_t)0x02)

#define GPIO_PortSourceGPIOD       ((uint8_t)0x03)

#define GPIO_PortSourceGPIOE       ((uint8_t)0x04)

#define GPIO_PortSourceGPIOF       ((uint8_t)0x05)

#define GPIO_PortSourceGPIOG       ((uint8_t)0x06)

GPIO_PinSource取值如下:

#define GPIO_PinSource0            ((uint8_t)0x00)

#define GPIO_PinSource1            ((uint8_t)0x01)

#define GPIO_PinSource2            ((uint8_t)0x02)

#define GPIO_PinSource3            ((uint8_t)0x03)

#define GPIO_PinSource4            ((uint8_t)0x04)

#define GPIO_PinSource5            ((uint8_t)0x05)

#define GPIO_PinSource6            ((uint8_t)0x06)

#define GPIO_PinSource7            ((uint8_t)0x07)

#define GPIO_PinSource8            ((uint8_t)0x08)

#define GPIO_PinSource9            ((uint8_t)0x09)

#define GPIO_PinSource10           ((uint8_t)0x0A)

#define GPIO_PinSource11           ((uint8_t)0x0B)

#define GPIO_PinSource12           ((uint8_t)0x0C)

#define GPIO_PinSource13           ((uint8_t)0x0D)

#define GPIO_PinSource14           ((uint8_t)0x0E)

#define GPIO_PinSource15           ((uint8_t)0x0F)

这里四个按键对应中断线映射:

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0 );

GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2 );

GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource3 );

GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4 );

4、配置中断分组(NVIC),使能中断

voidNVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

voidNVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

这里如下调用:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

//对GPIO_0,映射到EXTI0

NVIC_InitTypeDef NVIC_Struct;

NVIC_Stuct.NVIC_IRQChannel = EXTI0_IRQn;

NVIC_Stuct.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_Stuct.NVIC_IRQChannelSubPriority = 3;

NVIC_Stuct.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init( &NVIC_Struct );

5、初始化EXTI,选择触发方式

调用EXTI库函数EXTI_Init实现,该函数原型为:

voidEXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

在"stm32f10x_exti.h"文件中定义了以下结构体和宏:

typedef struct

{

  uint32_t EXTI_Line;                  /*指定要使能或失能的中断或事件线*/

  EXTIMode_TypeDef EXTI_Mode;       /*指定中断线的模式*/

  EXTITrigger_TypeDef EXTI_Trigger;     /*设置触发方式*/

  FunctionalState EXTI_LineCmd;         /*使能或失能 ENABLE or DISABLE */

}EXTI_InitTypeDef;

#define EXTI_Line0       ((uint32_t)0x00001)  /* External interrupt line 0 */

#define EXTI_Line1       ((uint32_t)0x00002)  /* External interrupt line 1 */

#define EXTI_Line2       ((uint32_t)0x00004)  /* External interrupt line 2 */

#define EXTI_Line3       ((uint32_t)0x00008)  /* External interrupt line 3 */

#define EXTI_Line4       ((uint32_t)0x00010)  /* External interrupt line 4 */

#define EXTI_Line5       ((uint32_t)0x00020)  /* External interrupt line 5 */

#define EXTI_Line6       ((uint32_t)0x00040)  /* External interrupt line 6 */

#define EXTI_Line7       ((uint32_t)0x00080)  /* External interrupt line 7 */

#define EXTI_Line8       ((uint32_t)0x00100)  /* External interrupt line 8 */

#define EXTI_Line9       ((uint32_t)0x00200)  /* External interrupt line 9 */

#define EXTI_Line10      ((uint32_t)0x00400)  /* External interrupt line 10 */

#define EXTI_Line11      ((uint32_t)0x00800)  /* External interrupt line 11 */

#define EXTI_Line12      ((uint32_t)0x01000)  /* External interrupt line 12 */

#define EXTI_Line13      ((uint32_t)0x02000)  /* External interrupt line 13 */

#define EXTI_Line14      ((uint32_t)0x04000)  /* External interrupt line 14 */

#define EXTI_Line15      ((uint32_t)0x08000)  /* External interrupt line 15 */

#define EXTI_Line16      ((uint32_t)0x10000)  /* External interrupt line 16 Connected to the PVD Output */

#define EXTI_Line17      ((uint32_t)0x20000)  /* External interrupt line 17 Connected to the RTC

Alarm event */

#define EXTI_Line18      ((uint32_t)0x40000)  /* External interrupt line 18 Connected to the

USB Device/USB OTG FS    Wakeup from suspend event */

#define EXTI_Line19      ((uint32_t)0x80000)  /* External interrupt line 19 Connected to the

Ethernet Wakeup event */

typedef enum

{

  EXTI_Mode_Interrupt = 0x00,   //设置EXTI线路为中断请求

  EXTI_Mode_Event = 0x04      //设置EXTI线路为事件请求

}EXTIMode_TypeDef;

typedef enum

{

  EXTI_Trigger_Rising = 0x08,        //设置输入线路上升沿为中断请求

  EXTI_Trigger_Falling = 0x0C,       //设置输入线路下降沿为中断请求

  EXTI_Trigger_Rising_Falling = 0x10  //设置输入线路上升沿和下降沿为中断请求

}EXTITrigger_TypeDef;

这里分别对0,2,3,4四个外部中断进行设置:

对K_UP键中断设置,根据电路连接,因为该键设置为下拉方式,在没有按下时为低电平,按下时为高电平,所以应设为上升沿触发。

EXTI_InitTypeDef EXTI_Struct;

EXTI_Struct.EXTI_Line = EXTI_Line0;

EXTI_Struct.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_Struct.EXTI_Trigger = EXTI_Trigger_Rising;

EXTI_Struct.EXTI_LineCmd = ENABLE;

EXTI_Init( &EXTI_Struct );

另外3个类似操作。

6、设置中断处理函数

中断服务函数有固定的函数名,在startup_stm32f10x_hd.s文件中已经定义,这里的四个中断的函数名分别为:EXTI0_IRQHandler、EXTI2_IRQHandler、EXTI3_IRQHandler和EXTI4_IRQHandler。

void EXTI0_IRQHandler( void )

{

         if( EXTI_GetITStatus( EXTI_Line0 ) ==1)

         {

                  delay_ms(10);

                  if(K_UP==1)

                  {

                            Sound(262);

                  }

         }

         EXTI_ClearITPendingBit( EXTI_Line0 );

}

四、项目实现

1、本项目以使用STM32GPIO读取按键实现按键操作为基础(代码下载地址)。

2、由于本项目需要用到EXTI相关库函数,所以将"stm32f10x_exti.h"、"stm32f10x_exti.c"两个文件分别复制到项目文件夹的"Lib/inc"和"Lib/src"子文件夹下,并将"stm32f10x_exti.c"文件加入到项目的"Lib "组中。

3、在项目文件夹下的"User"子文件夹下新建"Exti"子文件夹,在Keil5中新建"Exti.h"和"Exti.c"文件,并将"Exti.c"文件加入到项目的"User "组中,然后修改"Include Paths",添加".\User\Exti"路径,以便项目中其他程序能够引用"Exti.h"。

4、在"Exti.h"文件中添加相应的宏定义和函数声明,内容如下:

#ifndef __EXTI__H

#define __EXTI__H

#include "system.h"

#include "stm32f10x_exti.h"

void KEY_EXTI_Init(void);

#endif

5、在"Exti.c"文件中实现KEY_EXTI_Init函数和四个中断函数。

#include "exti.h"

#include "key.h"

#include "stm32f10x_rcc.h"

#include "misc.h"

#include "beep.h"

#include "systick.h"

void KEY_EXTI_Init(void)

{

         NVIC_InitTypeDef NVIC_Struct;

         EXTI_InitTypeDef  EXTI_Struct;

         //1、使能IO口时钟,配置IO口为输入模式

         Key_Init(); //调用key.c中的初始化按键GPIO的函数

         //2、开启AFIO时钟

         RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE );

         //3、设置IO口与中断线的映射关系

         GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0 );

         GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2 );

         GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource3 );

         GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4 );

         //4、配置中断分组(NVIC),使能中断

         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2 );

        

         NVIC_Struct.NVIC_IRQChannel = EXTI0_IRQn;

         NVIC_Struct.NVIC_IRQChannelPreemptionPriority = 2;

         NVIC_Struct.NVIC_IRQChannelSubPriority = 3;

         NVIC_Struct.NVIC_IRQChannelCmd = ENABLE;

         NVIC_Init( &NVIC_Struct );

         NVIC_Struct.NVIC_IRQChannel = EXTI2_IRQn;

         NVIC_Struct.NVIC_IRQChannelPreemptionPriority = 2;

         NVIC_Struct.NVIC_IRQChannelSubPriority = 3;

         NVIC_Struct.NVIC_IRQChannelCmd = ENABLE;

         NVIC_Init( &NVIC_Struct );

         NVIC_Struct.NVIC_IRQChannel = EXTI3_IRQn;

         NVIC_Struct.NVIC_IRQChannelPreemptionPriority = 2;

         NVIC_Struct.NVIC_IRQChannelSubPriority = 3;

         NVIC_Struct.NVIC_IRQChannelCmd = ENABLE;

         NVIC_Init( &NVIC_Struct );

         NVIC_Struct.NVIC_IRQChannel = EXTI4_IRQn;

         NVIC_Struct.NVIC_IRQChannelPreemptionPriority = 2;

         NVIC_Struct.NVIC_IRQChannelSubPriority = 3;

         NVIC_Struct.NVIC_IRQChannelCmd = ENABLE;

         NVIC_Init( &NVIC_Struct );

         //5、使能EXTI,选择触发方式

         //K_UP设为上升沿触发

         EXTI_Struct.EXTI_Line = EXTI_Line0;

         EXTI_Struct.EXTI_Mode = EXTI_Mode_Interrupt;

         EXTI_Struct.EXTI_Trigger = EXTI_Trigger_Rising;

         EXTI_Struct.EXTI_LineCmd = ENABLE;

         EXTI_Init( &EXTI_Struct );

        

         //K_LEFT,K_DOWN,K_RIGHT设为下降沿触发

         EXTI_Struct.EXTI_Line = EXTI_Line2|EXTI_Line3|EXTI_Line4;

         EXTI_Struct.EXTI_Mode = EXTI_Mode_Interrupt;

         EXTI_Struct.EXTI_Trigger = EXTI_Trigger_Rising;

         EXTI_Struct.EXTI_LineCmd = ENABLE;

         EXTI_Init( &EXTI_Struct );

}

void EXTI0_IRQHandler(void)

{

         u8 i;

         if( EXTI_GetITStatus( EXTI_Line0 ) == 1)

         {

                   delay_ms(10);

                   if(K_UP==1)

                   {

                            for(i=0; i<100;i++)

                                     Sound(262);

                   }

         }

         EXTI_ClearITPendingBit(EXTI_Line0);

}

void EXTI2_IRQHandler(void)

{

         u8 i;

         if( EXTI_GetITStatus( EXTI_Line2 ) == 1)

         {

                   delay_ms(10);

                   if(K_LEFT==0)

                   {

                            for(i=0; i<100;i++)

                                     Sound(294);

                   }

         }

         EXTI_ClearITPendingBit(EXTI_Line2);

}

void EXTI3_IRQHandler(void)

{

         u8 i;

         if( EXTI_GetITStatus( EXTI_Line3 ) == 1)

         {

                   delay_ms(10);

                   if(K_DOWN==0)

                   {

                            for(i=0; i<100;i++)

                                     Sound(330);

                   }

         }

         EXTI_ClearITPendingBit(EXTI_Line3);

}

void EXTI4_IRQHandler(void)

{

         u8 i;

         if( EXTI_GetITStatus( EXTI_Line4 ) == 1)

         {

                   delay_ms(10);

                   if(K_RIGHT==0)

                   {

                            for(i=0; i<100;i++)

                                     Sound(349);

                   }

         }

         EXTI_ClearITPendingBit(EXTI_Line4);

}

6、修改"main.c"文件,内容如下:

#include "SysTick.h"

#include "exti.h"

#include "beep.h"

int main()

{

         SysTick_Init(72);

         BEEP_Init();

         KEY_EXTI_Init();

         while(1)

         {

         }

}

7、编译,下载到开发板

猜你喜欢

转载自blog.csdn.net/fanxp66/article/details/80290253