其他分享
首页 > 其他分享> > 外部中断(含基础知识)-(做明白人)

外部中断(含基础知识)-(做明白人)

作者:互联网

目录

一、中断的基本知识

1.什么是中断

2.中断的优先级

二、代码区

1.中断函数功能定义

2.按键功能定义

3.功能调用


一、中断的基本知识

接下来得内容我会从中断得原理,中断的配置,如何使用原理图,一步步走起,如果有同学先前已经学过中断的可以先跳,直接进入代码区。 

1.什么是中断

中断就是当一个主程序正在执行时,遇到一个中断点 (好比一个闹钟)开始进行中断函数里面的内容,等在中断函数(或内容)跑完后,再重新回到主程序继续执行。通俗点 :就是你正在写作业,你的兄弟叫你上分,然后你放下作业开始上分,然后你的兄弟一直送,你打不下去了,又重新去写作业。

2.中断的优先级

为什么会有出现中断优先级这种现象呢?就是因为假如你一个主函数,它出现了两个中断,但两个中断呢,他又是同时发生,编译器或者系统,他就不知道哪一个中断先跑,所以这时候他就懵了,就好比说你两个老师都给你打电话,你都不知道该接谁的好。

这样的话,你就要分设置中断优先级设置中断优先级的话,它的这个优先级怎么分呢?

这时候我们讲抢占和响应优先级。

我们先来讲抢占,我再来接响应,什么是抢占,我安排设置一个数字,看来排序来看一下这个中断谁先谁后好,抢占值越小的,它就会越早去执行这个中断,就好比一组里面我从零开始012345,这样的话,零,他就是最小的,这样那样的话他抢占级别最高,在很多中断都存在的时候。这样的话就他先开始执行中断。

但是我如果设置了中断,有两个中断的优先级都是零,那怎么办?而且同时发生,那怎么办?这时候我们就是设置响应,响应是在抢占优先级相同的情况下发挥作用,实行响应,设置响应,谁的响应值设置的越小那它的响应越高,但记住响应是在抢占优先级相同且同时触发中断时,响应才会有作用。

 (以组1为例)

这时候我们谈谈分组现象,就是简单的排序,就是每个组有不同的排序方法,选择不同组只是排序方法不同罢了,没啥区别。就像第零组他只有抢占位,没有响应,未响应为零,这样的话他执行什么抢占这样的话,就不存在那种嗯同时发生中断的情况下,谁去同时触发那个中断的时候两个都到时候谁先谁后的问题了,这样子存在,说谁先开始中断,没有那所谓的响应。
第一组的话,它是存在有一个响应位,这样的话他是怎么做呢?就是他先分三个排一下抢占的顺序,留一个为响应排;这样的话就留给可能发生一种现象,就是说中断同时发生,这时候呢。它就会执行响应,然后呢,响应越小的就越早去执行。

二、代码区

先进行功能模块的初始化使用。

1.中断函数功能定义

//exti.h
#ifndef __EXTI_H
#define __EXTI_H
#include "sys.h"  	
 
void EXTIX_Init(void);	//中断初始化声明		 					    
#endif

这个头文件,既可以防止编译器没有定义exti.h时补上内容又可以再已经有对应内容是规避它,不重复使用,防止报错。

#include "exti.h"
#include "delay.h" 
#include "led.h" 
#include "key.h"
#include "beep.h"
//中断0
void EXTI0_IRQHandler(void)
{
	delay_ms(10);	//延迟消抖
	if(WK_UP==1)	 
	{
		BEEP=!BEEP;  
	}		 
	 EXTI_ClearITPendingBit(EXTI_Line0); //清除标志位
}	

void EXTIX_Init(void)
{
	NVIC_InitTypeDef   NVIC_InitStructure;
	EXTI_InitTypeDef   EXTI_InitStructure;
	
	KEY_Init(); //按键初始化
 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//时钟使能
	
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//PA0 连接中断线0
	

  EXTI_InitStructure.EXTI_Line = EXTI_Line0;//LINE0
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//出发中断事件
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中断通道使能
  EXTI_Init(&EXTI_InitStructure);//ÅäÖÃ
	
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//外部中断0
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//抢占优先级0
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//响应优先级2(或者子优先级2)
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能通道
  NVIC_Init(&NVIC_InitStructure);//配置
	   
}

使用按键要进行按键的消抖,防止接触不佳引发电平变化 不好,而在这里面有一个上升沿触发,这就要看你的对应的原理图。

你用的是按键,那就看按键的另一端是啥,存在高电平,就用上升沿,存在低电平就用下升。

2.按键功能定义

//key.h
#ifndef _KEY_H
#define _KEY_H
#include "sys.h" 
typedef unsigned char u8;

#define WK_UP PAin(0)
#define WK_UP_PRES 4


void KEY_Init(void);
u8 KEY_Scan(u8 mode);

#endif

这里假如不知道怎么配引脚可以在我之前的https://blog.csdn.net/weixin_51471186/article/details/118836090?spm=1001.2014.3001.5501看。

#include "key.h"
#include "sys.h"
#include "delay.h"

void KEY_Init(void)
{
	GPIO_InitTypeDef GPIO_Initstructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
	
	GPIO_Initstructure.GPIO_Pin=GPIO_Pin_0;
	GPIO_Initstructure.GPIO_PuPd=GPIO_PuPd_DOWN;
	GPIO_Init(GPIOA,&GPIO_Initstructure);
	
}

u8 KEY_Scan(u8 mode)
{

	if(key_up&&WK_UP==1) 
	{
		delay_ms(10);
		if(WK_UP==1)return 4;
	}
	return 0;
}

3.功能调用

接着就是main.c主函数在那时调用初始化和使用它。

#include "sys.h"
#include "delay.h"
#include "usart.h"

#include "beep.h"
#include "key.h"
#include "exti.h"


int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//选择优先级组别
	delay_init(168);    //延迟初始化
	BEEP_Init();        //蜂鸣器初始化
	EXTIX_Init();       //中断初始化
	while(1);
}

 更多好料转载至http://blog.qmgua.com/?id=180

 

标签:优先级,中断,基础知识,NVIC,InitStructure,include,明白人,EXTI
来源: https://blog.csdn.net/weixin_51471186/article/details/119015434