Stm32f407zgt6学习笔记3——外部中断

外部中断

1、定义
中断,意味着中途打断现在干的事情,要立即处理紧急的事件。
2.多达 140 个 GPIO(STM32F405xx/07xx 和 STM32F415xx/17xx)通过以下方式连接到 16 个外部中断/事件线。
例如:PA0占用了EXTI0,其他PB0~PI0是不能使用的。

在这里插入图片描述
引脚编号决定了对应哪个外部中断。

二、代码思路

1.8051单片机
外部中断的触发方式:低电平触发、下降沿触发 IT0=1
允许外部中断引脚申请中断请求 EX0=1
优先级的配置
中断服务函数

2.STM32
端口A硬件时钟使能
SYSCFG硬件时钟使能
配置引脚的工作模式
将引脚连接到外部中断
中断触发方式:电平触发、边沿触发
允许外部中断引脚申请中断请求
优先级的配置
中断服务函数

注:
中断服务函数是不能被调用,编写格式不能随意编写,这是它特有的存在形式。不同的硬件平台,其编写方法是不一样的。

三、中断优先级

中断优先级的一个意义:出现多个中断同时触发,但是不能同时处理,所以先后顺序之分,要根据实际上的运行环境优先处理重要的中断。
1.概述
STM32 对中断优先级进行分组,共 5 组,组 0~4,这些分组是用于指定当前M4支持多少个抢占优先级和多少个响应优先级。同时,对每个中断设置一个抢占优先级和一个响应优先级。函数原型如下:

/**
  * @brief  Configures the priority grouping: pre-emption priority and subpriority.
  * @param  NVIC_PriorityGroup: specifies the priority grouping bits length. 
  *   This parameter can be one of the following values:
  *     @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority    //不支持抢占优先级
  *                                4 bits for subpriority             //支持16个响应优先级
  *     @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority    //支持2个抢占优先级
  *                                3 bits for subpriority             //支持8个响应优先级
  *     @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority    //支持4个抢占优先级
  *                                2 bits for subpriority             //支持4个响应优先级
  *     @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority    //支持8个抢占优先级
  *                                1 bits for subpriority             //支持2个响应优先级
  *     @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority    //支持16个抢占优先级
  *                                0 bits for subpriority             //不支持响应优先级
  * @note   When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. 
  *         The pending IRQ priority will be managed only by the subpriority. 
  * @retval None
  */
void NVIC_PriorityGroupConfig(uint32_t, NVIC_PriorityGroup)

只要开机初始化一次就可以了。

2.抢占优先级与响应优先级区别
1)高抢占优先级是可以打断正在进行的低抢占优先级的中断。抢占优先级若相同,则不会出现抢占的过程。
2)抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
3)抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
4)抢占优先级相同且响应优先级相同的中断,假如同时发生,会按照硬件内部固定的优先级执行
5)无论是抢占优先级还是响应优先级,优先级数值越小,就代表优先级越高。

四、中断服务函数

要记得清除标志位,告诉CPU,已经完成中断处理。

下面是相关代码及注释
exti.c

#include "stm32f4xx.h"
#include "sys.h"


static GPIO_InitTypeDef 	GPIO_InitStructure;
static EXTI_InitTypeDef   	EXTI_InitStructure;
static NVIC_InitTypeDef   	NVIC_InitStructure;

void delay(void)
{
	uint32_t i=0x2000000;
	
	while(i--);
}


void exti0_init(void)
{
	//使能(打开)端口A的硬件时钟,就是对端口A供电
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	
	
	//使能系统配置时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
	
	//配置PA0引脚为输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		//第0根引脚
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN;		//输入模式
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//高速响应
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	//没有使能上下拉电阻
	GPIO_Init(GPIOA,&GPIO_InitStructure);	


	//将PA0和EXTI0连接在一起
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

	//外部中断的配置
	EXTI_InitStructure.EXTI_Line = EXTI_Line0;		//外部中断0
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;		//中断
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;	//下降沿触发,用于识别按键的按下;上升沿触发,用于检测按键的松开;  
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;				//使能
	EXTI_Init(&EXTI_InitStructure);
	
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			//外部中断0的请求通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级0x02
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;		//响应优先级0x03
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能该通道
	NVIC_Init(&NVIC_InitStructure);
	
}

void exti2_init(void)
{
	//使能(打开)端口E的硬件时钟,就是对端口E供电
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
	
	
	//使能系统配置时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
	
	
	
	//配置PE2引脚为输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;		//第2根引脚
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN;		//输入模式
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//高速响应
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	//没有使能上下拉电阻
	GPIO_Init(GPIOE,&GPIO_InitStructure);	


	//将PE2和EXTI2连接在一起
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);

	//外部中断的配置
	EXTI_InitStructure.EXTI_Line = EXTI_Line2;		//外部中断2
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;		//中断
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;	//下降沿触发,用于识别按键的按下;上升沿触发,用于检测按键的松开;  
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;				//使能
	EXTI_Init(&EXTI_InitStructure);
	
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;			//外部中断2的请求通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;//抢占优先级0x03
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;		//响应优先级0x03
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能该通道
	NVIC_Init(&NVIC_InitStructure);
	
}

int main(void)
{
	
		
	
	//使能(打开)端口F的硬件时钟,就是对端口F供电
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);


	//初始化GPIO引脚
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;		//第9 10根引脚
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_OUT;	//输出模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;	//推挽输出,增加输出电流能力。
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//高速响应
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	//没有使能上下拉电阻

	GPIO_Init(GPIOF,&GPIO_InitStructure);
	
	PFout(9)=1;
	PFout(10)=1;

	
	//中断优先级的组配置:选择第二组
	//优先级,数值越小,优先级就越高
	//支持4个抢占优先级:0~3
	//支持4个响应优先级:0~3
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	
	//exti0初始化
	exti0_init();
	
	//exit2初始化
	exti2_init();
	
	while(1)
	{
		

	}
}

void EXTI0_IRQHandler(void)
{

	//判断是否有中断请求
	if(EXTI_GetITStatus(EXTI_Line0) == SET)
	{
		//点亮LED1
		PFout(9)=0;
		
		//延时一会
		delay();
		
		//熄灭LED1
		PFout(9)=1;
		
		//延时一会
		delay();		
	
		/* 清空标志位,告诉CPU,已经完成当前中断处理;可以响应新的中断请求*/
		EXTI_ClearITPendingBit(EXTI_Line0);
	}

}

void EXTI2_IRQHandler(void)
{

	//判断是否有中断请求
	if(EXTI_GetITStatus(EXTI_Line2) == SET)
	{
		//点亮LED2
		PFout(10)=0;
		
		//延时一会
		delay();
		
		//熄灭LED2
		PFout(10)=1;
		
		//延时一会
		delay();		
	
		/* 清空标志位,告诉CPU,已经完成当前中断处理;可以响应新的中断请求 */
		EXTI_ClearITPendingBit(EXTI_Line2);
	}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值