二、外部中断/事件控制器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”,添加“。UserExti”路径,以便项目中其他程序能够引用“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、编译,下载到开发板
二、外部中断/事件控制器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”,添加“。UserExti”路径,以便项目中其他程序能够引用“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、编译,下载到开发板
举报