外部中断实验

需要添加的固件库文件有 misc.c、stm32f4xx_exti.c、stm32f4xx_gpio.c、stm32f4xx_rcc.c、stm32f4xx_syscfg.c 五个。

1) 使能 IO 口时钟,初始化 IO 口为输入
首先,我们要使用 IO 口作为中断输入,所以我们要使能相应的 IO 口时钟,以及初始化相应的 IO 口为输入模式,具体的使用方法在按键模块完成。

//按键IO口初始化函数
void KEY_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);    //使能GPIOF时钟
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9; //KEY0 KEY1 KEY2 KEY3对应引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;             //普通输入模式
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;       //100M
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;             //上拉
  GPIO_Init(GPIOF, &GPIO_InitStructure);                   //初始化GPIOF6,7,8,9
} 

2) 开启 SYSCFG 时钟,设置 IO 口与中断线的映射关系。
接下来,要配置 GPIO 与中断线的映射关系,那么我们首先需要打开SYSCFG 时钟。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能 SYSCFG 时钟 

这里一定要注意,只要我们使用到外部中断,就必须打开 SYSCFG 时钟。接下来,配置 GPIO 与中断线的映射关系。在库函数中,配置 GPIO 与中断线的映射关系的函数 SYSCFG_EXTILineConfig ()来实现的:

void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex); 

该函数将 GPIO 端口与中断线映射起来,使用如下:

//建立io口与中断线的映射关系
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource6); //PF6连接到中断线6
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource7); //PF6连接到中断线7
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource8); //PF6连接到中断线8
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource9); //PF6连接到中断线9

设置好中断 线映射之后,那么到底来自这个 IO 口的中断是通过什么方式触发的呢?接下来就要设置该中断线上中断的初始化参数了。

3) 初始化线上中断,设置触发条件等。
中断线上中断的初始化是通过函数 EXTI_Init()实现的。EXTI_Init()函数的定义是:

void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct); 

具体使用如下:

// 初始化线上中断,设置触发条件等
	EXTI_InitStructure.EXTI_Line=EXTI_Line6 | EXTI_Line7 | EXTI_Line8 | EXTI_Line9; //中断线6-9
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling; //下降沿触发
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; //中断事件
	EXTI_InitStructure.EXTI_LineCmd=ENABLE; //使能中断线
	EXTI_Init(&EXTI_InitStructure); //初始化中断线

4) 配置中断分组(NVIC),并使能中断。
我们设置好中断线和 GPIO 映射关系,然后又设置好了中断的触发模式等初始化参数。既然是外部中断,涉及到中断我们当然还要设置 NVIC 中断优先级。

//配置中断分组(NVIC),并使能中断
	NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn; //使能外部按键中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0x02; //抢占优先级2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02; //响应优先级2
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能中断通道
	NVIC_Init(&NVIC_InitStructure);           //中断优先级分组初始化

5) 编写中断服务函数。
我们配置完中断优先级之后,接着我们要做的就是编写中断服务函数。中断服务函数的名字是在 MDK 中事先有定义的。这里需要说明一下,STM32F4 的 IO 口外部中断函数只有 7 个,分别为:

EXPORT  EXTI0_IRQHandler           
EXPORT  EXTI1_IRQHandler        
EXPORT  EXTI2_IRQHandler          
EXPORT  EXTI3_IRQHandler 
EXPORT  EXTI4_IRQHandler           
EXPORT  EXTI9_5_IRQHandler         
EXPORT  EXTI15_10_IRQHandler 

中断线 0-4 每个中断线对应一个中断函数,中断线 5-9 共用中断函数 EXTI9_5_IRQHandler,中断线 10-15 共用中断函数 EXTI15_10_IRQHandler。

//外部中断服务函数
void EXTI9_5_IRQHandler(void) 
{    
	delay_ms(10); //消抖 
	if(KEY0==0)   
		LED0=!LED0;  //LED反转
	else if(KEY1==0)
		LED1=!LED1;
	else if(KEY2==0)
		LED2=!LED2;
    EXTI_ClearITPendingBit(EXTI_Line6); //清除 LINE6 上的中断标志位  
	EXTI_ClearITPendingBit(EXTI_Line7); //清除 LINE7 上的中断标志位
	EXTI_ClearITPendingBit(EXTI_Line8); //清除 LINE8 上的中断标志位
	EXTI_ClearITPendingBit(EXTI_Line9); //清除 LINE9 上的中断标志位
}  

6) 软件设计
exti.c

#include "key.h"
#include "common.h"
#include "led.h"
#include "exti.h"






//外部中断服务函数
void EXTI9_5_IRQHandler(void) 
{    
	delay_ms(10); //消抖 
	if(KEY0==0)   
		LED0=!LED0;  //LED反转
	else if(KEY1==0)
		LED1=!LED1;
	else if(KEY2==0)
		LED2=!LED2;
  EXTI_ClearITPendingBit(EXTI_Line6); //清除 LINE6 上的中断标志位  
	EXTI_ClearITPendingBit(EXTI_Line7); //清除 LINE7 上的中断标志位
	EXTI_ClearITPendingBit(EXTI_Line8); //清除 LINE8 上的中断标志位
	EXTI_ClearITPendingBit(EXTI_Line9); //清除 LINE9 上的中断标志位
}  


//初始化PF6-PF9为中断输入
void EXTIX_Init(void)
{

	NVIC_InitTypeDef   NVIC_InitStructure; 
  EXTI_InitTypeDef   EXTI_InitStructure; 
	
	KEY_Init(); //按键初始化
	LED_Init(); //LED初始化
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能 SYSCFG 时钟 
	
	//建立io口与中断线的映射关系
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource6); //PF6连接到中断线6
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource7); //PF6连接到中断线7
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource8); //PF6连接到中断线8
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource9); //PF6连接到中断线9

	// 初始化线上中断,设置触发条件等
	EXTI_InitStructure.EXTI_Line=EXTI_Line6 | EXTI_Line7 | EXTI_Line8 | EXTI_Line9; //中断线6-9
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling; //下降沿触发
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; //中断事件
	EXTI_InitStructure.EXTI_LineCmd=ENABLE; //使能中断线
	EXTI_Init(&EXTI_InitStructure); //初始化中断线
	
	//配置中断分组(NVIC),并使能中断
	NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn; //使能外部按键中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0x02; //抢占优先级2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02; //响应优先级2
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能中断通道
	NVIC_Init(&NVIC_InitStructure);           //中断优先级分组初始化

}

exti.h

#ifndef __EXTI_H
#define __EXTI_H	 


void EXTI9_5_IRQHandler(void);  //中断服务函数
void EXTIX_Init(void);     //外部中断初始化函数

#endif

main.c

#include "common.h"
#include "exti.h"
#include "led.h"


int main(void)
{ 
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置系统中断优先级分组2
	delay_init();		  //初始化延时函数
	EXTIX_Init();//初始化外部中断函数
	LED0=0;     //先点亮红灯 
  while(1)
	{
    delay_ms(1000);
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值