外部中断设置

中断

中断机制:主程序正常运行时,【发生中断事件】打断CPU运行,保存任务的地址(栈空间,先进后出,【压栈】)。转而【执行中断服务程序】(快进快出无参无返回),执行完成后,在将主函数运行状态出栈。

内核中断数:1~240 32中有64个和16个可编程的

中断事件:

中断优先级在ST芯片中分为4个组。如图所示

红色部分就是ST的

首先,对STM32中断进行分组,组0~4。同时,对每个中断设置一个抢占优先级和一个响应优先级值。分组配置是在寄存器SCB->AIRCR中配置(注意:数字越小,优先级越高):

  • 第0组: 所有4位用于指定响应优先级

  • 第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级

  • 第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级

  • 第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级

  • 第4组:所有4位用于指定抢占式优先级

STM32 中断是怎么进入到中断服务程序的?

在STM32中,为了区分不同的中断,每个设备有自己的中断号。系统有0-255一共256个中断。系统有一张中断向量表,用于存放256个中断的中断服务程序入口地址。每个入口地址对应一段代码,即中断服务程序。

外部中断产生

1.外部I/O口对应中断线

2,设置触发寄存器 --上升沿触发,下降沿触发,双边触发

3,中断信号产生

4,中断屏蔽寄存器是否允许中断产生,允许中断产生 (这个中断屏蔽寄存器需要使能)

5,NVIC中断控制器便设置: (1)分组 (2)优先级 (3)使能中断通道(是否有处理这个中断的渠道)

6,处理中断:编写中断服务函数

注意:配置了某个中断,一定要写中断服务函数

中断服务函数里面一定要记得清中断

实例代码exti.c

#include "exti.h"
 
//粗延时
void  delayms(int n)
{
	int i, j;
	
	for(i=0; i<n; i++)
		for(j=0; j<40000; j++);
 
}
 
//PA0引脚按键KEY1中断初始化
void Exti_PA0_KEY1_Init(void)
{
	
//	GPIO_InitTypeDef  GPIO_InitStruct;
	EXTI_InitTypeDef  EXTI_InitStruct;
	NVIC_InitTypeDef  NVIC_InitStruct;
	
	//使能GPIO A组时钟,
//	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	
//	GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_0;		//引脚0
//	GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_IN;		//输入模式
//	GPIO_InitStruct.GPIO_PuPd	= GPIO_PuPd_UP;     //上拉
//	GPIO_Init(GPIOA, &GPIO_InitStruct);	
	
	//使能SYSCFG时钟: 
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
	//开这个时钟是因为在I/O对应中断线时,这个中断线在这个寄存器上,可以根据上面图看出来!
 
	
	//设置IO口与中断线的映射关系。确定什么引脚对应哪个中断线 PA0 -- EXTI0 (可变)
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);
	
	
	EXTI_InitStruct.EXTI_Line	= EXTI_Line0; 		//中断线0 (可变)
	EXTI_InitStruct.EXTI_Mode	= EXTI_Mode_Interrupt;	//中断模式
	EXTI_InitStruct.EXTI_Trigger= EXTI_Trigger_Falling;     //下降沿触发
	EXTI_InitStruct.EXTI_LineCmd= ENABLE;                   //中断线使能
	//初始化线上中断,设置触发条件等。
    EXTI_Init(&EXTI_InitStruct);
	
    
    //	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   //中断优先级分组 这里已经在main.c中编写过了,这里不用再分组了
    
	NVIC_InitStruct.NVIC_IRQChannel				= EXTI0_IRQn;  	//NVIC通道,在stm32f4xx.h可查看通道 (可变)
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority	= 0x01;		//抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority		= 0x01;		//响应优先级
	NVIC_InitStruct.NVIC_IRQChannelCmd			= ENABLE;	//使能
	//配置中断分组(NVIC),并使能中断。
    NVIC_Init(&NVIC_InitStruct);	
	
}
 

//编写中断服务函数。这个函数不需要程序员在主函数调用,满足条件CPU自行调用的函数
void EXTI0_IRQHandler(void)
{
	//判断中断标志是否为1
	if(EXTI_GetITStatus(EXTI_Line0) == SET)
	{
		delayms(15);  //延时消抖
		//判断是否按下
		if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0)
		{
			//变更灯状态
			GPIO_ToggleBits(GPIOF, GPIO_Pin_9);
		}
	}
	//清空标志位
	EXTI_ClearITPendingBit(EXTI_Line0);
 
}

对应的main.c

#include "stm32f4xx.h"
 #include "led.h"
 #include "key.h"
 #include "exti.h"
  
 int main(void)
 {
     //NVIC分组(一个工程当中只能配置一次分组)抢占优先级2位,值范围:0~3;响应优先级2位,值范围:0~3;
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
     //LED灯初始化
     Led_Init();
     //按键初始化
     Key_Init();
     //中断
     Exti_PA0_KEY1_Init();
  
     while(1)
     {
         GPIO_ToggleBits(GPIOE, GPIO_Pin_14);
         delayms(1000);
     }
     return 0;
 }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值