外部中断


热门范文 2019-09-14 14:06:11 热门范文
[摘要]篇一:[外部中断]外部中断设置一,中断优先级:STM32(Cortex-M3)中的优先级概念STM32(Cortex-M3)中有两个优先级的概念——抢占式优先级和响应优先级,有人把响应优先级称作亚优先级或副优先级,每个中断源都需要被指定这两种优先级。具有高抢占式优先级的中断可以在具有低抢占

【www.shanpow.com--热门范文】

篇一:[外部中断]外部中断设置


一,中断优先级:
 
STM32(Cortex-M3)中的优先级概念STM32(Cortex-M3)中有两个优先级的概念——抢占式优先级和响应优先级,有人把响应优先级称作"亚优先级"或"副优先级",每个中断源都需要被指定这两种优先级。
具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。
当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才
能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断
表中的排位顺序决定先处理哪一个。
既然每个中断源都需要被指定这两种优先级,就需要有相应的寄存器位记录每个中断的优先级;在Cortex-M3中定义了8个比特位用于设置中断源的优先级,这8个比特位
可以有8种分配方式,如下:
所有8位用于指定响应优先级最高1位用于指定抢占式优先级,最低7位用于指定响应优先级最高2位用于指定抢占式优先级,最低6位用于指定响应优先级最高3位用于指定抢占式优先级,最低5位用于指定响应优先级最高4位用于指定抢占式优先级,最低4位用于指定响应优先级最高5位用于指定抢占式优先级,最低3位用于指定响应优先级最高6位用于指定抢占式优先级,最低2位用于指定响应优先级最高7位用于指定抢占式优先级,最低1位用于指定响应优先级
这就是优先级分组的概念。
 
--------------------------------------------------------------------------------Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此STM32把指定中断优先级的寄存器位减少到4位,这4个寄存器位的分组方式如下:
第0组:所有4位用于指定响应优先级第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级第4组:所有4位用于指定抢占式优先级
可以通过调用STM32的固件库中的函数NVIC_PriorityGroupConfig()选择使用哪种优先级分组方式,这个函数的参数有下列5种:
NVIC_PriorityGroup_0 => 选择第0组NVIC_PriorityGroup_1 => 选择第1组NVIC_PriorityGroup_2 => 选择第2组NVIC_PriorityGroup_3 => 选择第3组NVIC_PriorityGroup_4 => 选择第4组
接下来就是指定中断源的优先级,下面以一个简单的例子说明如何指定中断源的抢占式优先级和响应优先级:
// 选择使用优先级分组第1组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  // 使能EXTI0中断NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 指定抢占式优先级别1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);  // 使能EXTI9_5中断NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
要注意的几点是:
1)如果指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果;
2)抢占式优先级别相同的中断源之间没有嵌套关系;
3)如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。
 
外部中断配置
 
 
 
1配置中断
1、 分配中断向量表:
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
2、 设置中断优先级:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //设置中断优先级
3、 初始化外部中断:
/*允许EXTI4中断 */
       NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQChannel; //中断通道
       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;//强占优先级
       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //次优先级
       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能
       NVIC_Init(&NVIC_InitStructure);       //初始化中断
注意:如果我们配置的外部针脚为PA4,或PB4,或PC4,PD4等,那么采用的外部中断也必须是EXTI4,同样,如果外部中断针脚是PA1,PB1,PC1,PD1 那么中断就要用
EXTI1,其他类推。
2配置GPIO针脚作为外部中断的触发事件
1、 选择IO针脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
注意,如果的针脚是端口的4号针脚,配置的中断一定是EXTI4
2、 配置针脚为输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
3、 初始化针脚
GPIO_Init(GPIOD,&GPIO_InitStructure);
3配置EXTI线,使中断线和IO针脚线连接上
1、 将EXTI线连接到IO端口上
将EXTI线4连接到端口GPIOD的第4个针脚上
       GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource4);
       注意:如果配置的针脚是4号,那么参数必须是GPIO_PinSource4
              如果配置的针脚是3号,那么参数必须是GPIO_PinSource3
2、配置中断边沿
       /*配置EXTI线0上出现下降沿,则产生中断*/
       EXTI_InitStructure.EXTI_Line = EXTI_Line4;
       注意:如果配置的4号针脚,那么EXTI_Line4是必须的
       EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
       EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
       EXTI_InitStructure.EXTI_LineCmd = ENABLE;     //中断线使能
       EXTI_Init(&EXTI_InitStructure);                 //初始化中断
       EXTI_GenerateSWInterrupt(EXTI_Line4);         //EXTI_Line4中断允许
到此中断配置完成,可以写中断处理函数。
举例:
配置函数
/*************************************************************************
* 函数名      NVIC_Configration
* 描述          配置各个中断寄存器
* 输入           无
* 输出           无
* 返回值       无
****************************************************************************/
void NVIC_Configration(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
//#ifdef VECT_TAB_RAM
      /* Set the Vector Table base location at 0x20000000 */
      NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
//#else /* VECT_TAB_FLASH */
      /* Set the Vector Table base location at 0x08000000 */
      //NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); 
//#endif 
       NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //设置中断优先级
       /*允许EXTI4中断 */
       NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQChannel;
       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;
       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
       NVIC_Init(&NVIC_InitStructure);     
       /*允许EXTI9中断*/
       NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
       NVIC_Init(&NVIC_InitStructure);     
       /*配置SysTick处理优先级:优先级以及子优先级*/
     
}
/************************************************************************
* 函数名       :GPIO_Configuration(void)
* 描述           :配置TIM2阵脚
* 输入           :无
* 输出      :无
* 返回           :无
************************************************************************/
void GPIO_Configuration(void){
/*    GPIO_InitTypeDef GPIO_InitStructure;
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_Init(GPIOA,&GPIO_InitStructure); */
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
       GPIO_Init(GPIOC,&GPIO_InitStructure);
       /*配置GPIOD的第一个管角为浮动输入*/
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
       GPIO_Init(GPIOD,&GPIO_InitStructure);
       /*配置GPIOB的第9个管脚为浮动输入*/
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
       GPIO_Init(GPIOB,&GPIO_InitStructure);
}

篇二:[外部中断]单片机外部中断详解及程序


单片机外部中断详解及程序 
单片机在自主运行的时候一般是在执行一个死循环程序,在没有外界干扰(输入信号)的时候它基本处于一个封闭状态。比如一个电子时钟,它会按时、分、秒的规律来自主运行并通过输出设备(如液晶显示屏)把时间显示出来。在不需要对它进行调校的时候它不需要外部干预,自主封闭地运行。如果这个时钟足够准确而又不掉电的话,它可能一直处于这种封闭运行状态。但事情往往不会如此简单,在时钟刚刚上电、或时钟需要重新校准、甚至时钟被带到了不同的时区的时候,就需要重新调校时钟,这时就要求时钟就必须具有调校功能。因此单片机系统往往又不会是一个单纯的封闭系统,它有些时候恰恰需要外部的干预,这也就是外部中断产生的根本原由。实际上在第二个示例演示中,就已经举过有按键输入的例子了,只不过当时使用的方法并不是外部中断,而是用程序查询的方式。下面就用外部中断的方法来改写一下第二个示例中,通过按键来更改闪烁速度的例子(第二个例子)。电路结构和接线不变,仅把程序改为下面的形式。#include <iom16.h>unsigned int t=500; //定义一个全局变量t,并设定初始值为500次//===========延时子函数,在8MHz晶振时约1ms=============void delay_ms(unsigned int k){unsigned int i,j;for(i=0;i<k;i++){for(j=0;j<1140;j++);}}//============主函数==================================void main( void ){DDRB = 0xFF; //设置端口B为输出方向PORTB = 0xFF; //设置端口B的输出为全高电平DDRD = 0x00; //设置端口D为输入方向PORTD = 0xFF; //设定端口D为内部上拉方式,无信号输入时处于高电平状态MCUCR = 0x0A; //设定INT0、INT1为下降沿触发GICR = 0xC0; //使能INT0、INT1中断SREG = 0x80; //使能总中断while(1){PORTB = 0x55; //让接在端口B上的LED显示01010101delay_ms(t); //延时t个msPORTB = 0xAA; //让接在端口B上的LED显示01010101delay_ms(t); //延时t个ms}}//============中断函数(外部0)==========================#pragma vector = INT0_vect__interrupt void INT0_Server(void){t = 100; //设定t的值为100次}//============中断函数(外部1)==========================#pragma vector = INT1_vect__interrupt void INT1_Server(void){t = 500; //设定t的值为500次}把上述程序进行编译并下载到单片机中,可以看到结果与第二个示例中的完全一致。下面就来分析一下键盘中断的程序原理。在分析程序之前,先来了解一下什么叫“外部中断”。前面已讲述过,在没有打扰的情况下,单片机的程序在封闭状态下自主运行,但如果在某一时刻需要响应一个外部事件(比如有按键被按下),这时就需要用外部中断。具体来讲,外部中断就是在单片机的一个引脚上,由于外部因素导致了一个电平的变化(比如由高变低),而通过捕获到这个变化,单片机内部自主执行的程序就被暂时打断,转而去执行相应的中断处理程序,执行完后又回到原来中断的地方继续执行原程序。这个引脚上的电平变化,就申请了一个外部中断事件,而这个能申请外部中断的引脚就是外部中断的触发引脚。在上面的例子中,可以看到两个按键S1、S2被接到了ATMega16的PD3和PD2引脚,而这两个引脚正是该单片机的两个外部中断(INT1和INT0)的触发引脚(第二功能)。当按键没有按下时,这两个引脚都为高电平(执行过PORTD=0xFF),当按键被按下时,引脚电平跳变为低电平,这时若单片机设置成允许中断申请,就会触发外部中断事件,从而转去执行中断服务程序。明白了这个过程之后,接下来就可以分析程序了。程序执行后,主程序就一直在不停的运行while(1)内的这个死循环,让LED以t=500ms的初始值来交替闪烁,直到有外部中断来打断它。假设某一时刻按键S2被按下,这时由于引脚PD2上的电平突然被拉低,申请了一个外部中断0(INT0),这时的程序就转去执行外部中断0的中断服务程序(即__interrupt void INT0_Server(void)函数)。这时全局变量t的值被该函数重新赋值为100(即延时为100ms),完成后又回到主函数中的while(1)内去继续执行,因此LED闪烁的速度就变快了。观察程序可看出,如果没有中断去调用中断服务子程序,在主程序中是没有语句去调动它的。也就是说如果没有外部中断,中断服务子程序(即__interrupt void INT0_Server(void)函数)是永远不会被执行的。这也说明,中断服务子程序是一类特殊的子程序,它不能被主程序调用,只能被中断申请调用。因此,中断服务子程序有它固定的格式和写法。在不同的编译系统中的写法不完全一样,下面给出IAR下的中断服务子程序的格式。#pragma vector = INT0_vect__interrupt void INT0_Server(void){中断服务程序代码}以上是固定格式,除斜体部分外,其余部分不可更改。斜体部分中的INT0_vect表示中断的向量号,不同的中断名称不一样(原型在头文件iom16.h中)。斜体部分中的INT0_Server是中断函数的名称,是由开发者自己定义的。虽然可以自定义,但名称还是要取得“见名知义”,这样一看就知道是什么中断服务了。

篇三:[外部中断]51单片机外部中断0实例详解


今天就以51单片机的外部中断0为例,来简单讲解一下单片机中断的用法。
151单片机的中断源
51单片机共有5个中断源,分别为:
外部中断0
定时器0中断
外部中断1
定时器1中断
串口中断
每一个中断都对应一个中断向量,中断向量表如下所示:
2什么是中断事件
当中断发生时单片机将正在执行的程序暂时放下而去处理中断事件,当中断事件处理完毕后再接着去处理之前的事情,这样可以大大降低单片机的资源,提高执行效率。举个例子说明一下什么是中断:
我很喜欢打CS,每天晚上我都会抽时间打CS,但同时厨房里正在烧水,为了不使水烧干,我每隔5分钟就去厨房看一下水有没开,但这就错过了游戏老被别人爆头干掉,我很苦恼,怎么办。于是我在网上买了一个水烧开就会叫的水壶,这样我就不用每隔5分钟去厨房了从而可以专心的打游戏,只有听到水壶吱吱叫的时候,我去把水倒出来就可以了。
在这个例子里,打游戏就是主任务,水烧开就是中断,吱吱叫就是中断向量,听到吱吱响我就明白水烧开了,这时我要把打游戏这个主任务暂时放下,转而去处理水烧开了这个中断事件,水倒完后我就又回到了游戏这个主任务中。这样是不是提高了打游戏的效率呢?
3中断的硬件实现
51单片机的外部中断0引脚接一只按键,该按键通过上拉电阻接到电源,即没有按键发生时单片机检测到的是高电平,当按键按下时单片机检测到的是低电平。单片机的P0.0引脚以灌电流的方式接了一只LED,当按键按下时LED灯点亮,没按键时LED灯熄灭。
4中断的软件实现
单片机中断函数的写法比较固定,51单片机中断函数的写法如下:
void Initd() interrupt 0
其中:
void:为中断函数的返回类型,中断函数多为空类型;
Initd():是中断函数的名称,这个函数名符合C语言函数命名规范就可以,随便起;
interrupt:为51单片机中断的关键字,必须这么写(51单片机必须这么写);
0:为中断向量,该值详看第一个表格,如果是外部中断1就写2,如果是定时器1中断就写3;
中断函数不用在主函数中调用,只要中断事件发生,单片机自己主动会调到中断函数中。
该例子的函数如下所示:
5仿真实现
当按键发生时,LED灯点亮,如下图所示。注意对比两种图中按键的状态。
本订阅号致力于单片机、ARM等嵌入式软硬件的设计经验分享,秉承“人人都是电子设计经验的分享者”的理念,成功路上不孤单,我们一起努力。公众号:micropoint8,对于本节内容欢迎大家讨论。

本文来源:https://www.shanpow.com/news/452687/

《外部中断.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式

相关阅读
  • 《中国九年义务教育歌》 《中国九年义务教育歌》
  • 员工作业效率算法说明 员工作业效率算法说明
  • 补入党介绍人证明 补入党介绍人证明
  • 严字当头确保全面从严治党主体责任落地落实 严字当头确保全面从严治党主体责任落地落实
  • 被巡察单位党组工作汇报材料 被巡察单位党组工作汇报材料
  • 疫情防控党课讲稿大全 疫情防控党课讲稿大全
  • 疫情防控事迹材料 疫情防控先进个人事迹材料 疫情防控事迹材料 疫情防控先进个人事迹材料
  • 大学生读书笔记1000字 大学生读书笔记1000字
为您推荐