中断

瑞萨电子RH850系列32位MCU符合ISO26262的要求,满足汽车安全等级ASILB -ASILD等级的控制芯片,在全球汽车电子市场上得到广泛应用,获得著名汽车厂商的认可。

本文向工程师简单介绍RH850系列MCU的中断部分,以帮助工程师更好的使用RH850系列MCU进行开发。

RH850的中断从功能上分为三种,FE级不可屏蔽中断,FE级可屏蔽中断,以及EI级可屏蔽中断。其中FE级代表芯片功能性的中断,以辅助工程师了解MCU内部出错的来源。EI级可屏蔽中断中断是我们定义的各个功能模块所产生的中断。

三者的优先级顺序为:FE级不可屏蔽中断 > FE级可屏蔽中断 > EI级可屏蔽中断。

FE级不可屏蔽中断:在芯片R7F7010323中表现为两个WDT中断,任何情况不可屏蔽。

FE级可屏蔽中断:包括位错误,RAM错误,以及低压检查等中断,可设置PSW.NP=1来屏蔽该种类型中断。

EI级可屏蔽中断:即是我们定义的功能性中断如CAN接收中断,定时器中断等。

其中EI级可屏蔽中断即是我们最常接触的中断,在RH850中最高可分为16个优先等级。每个EI级中断,以功能模块命名,如定时器TAUD0的通道2中断命名为INTTAUD0I2。中断配置相关的寄存器为ICTAUD0I2。

系统中默认以优先级形式进入中断入口,中断入口函数定义可参照如下程序:

#pragma interrupt priority7_interrupt( enable=false , priority=EIINT_PRIORITY7 , callt=false , fpu=false )
void priority7_interrupt( uint32_t regEIIC_value )
{
test = regEIIC_value;
    switch ( regEIIC_value )
    {
       	case 0x0000100AUL: /* INTADCA0I0 *
               */
        break;
}

此外系统中也定义了宏定义来方便我们处理中断操作:
DI():关闭EI级中断
EI():允许EI级中断

也可以调用以下内置函数set_il_rh来配置中断优先级和屏蔽使能功能:

1、函数__set_il_rh(int interrupt-priority-level, void* address of interrupt control register);设置对应地址中断的中断优先级,
interrupt-priority-level 范围0~15。

2、以上的函数 interrupt-priority-level值如下表格时,对应的功能如下:

RH850系列32位MCU三种中断功能,你知道么?

图1:中断屏蔽功能选项

来源:世强元件电商

围观 3
38

一、stm32的中断和异常

Cortex拥有强大的异常响应系统,它能够打断当前代码执行流程事件分为异常和中断,它们用一个表管理起来,编号为0~15为内核异常,16以上的为外部中断,这个表就是中断向量表。而stm32对这个表重新进行了编排,把编号从-3~6定义为系统异常,编号为负的内核异常不能设置优先级,从编号为7为外部中断,这些中断的优先级可自行进行设置。我们一般在starup_stm32f10x_hd.s中查找中断向量,而且在编写中断函数时也要在这个文件里查找中断服务函数的函数名。如下图所示:

stm32之中断配置

二、NVIC中断控制器

1、stm32提供了强大的中断控制器NVIC,NVIC属于Cortex内核器件,不可屏蔽中断(NMI)和外部中断都由它来管理,而SYSTICK不由它管理。

在misc.h文件中我们对NVIC进行了结构体定义,我们找到NVIC_InitTypeDef结构体就可进行定义,结构体中包含四个成员,分别是:

  NVIC_IRQChannel :需要配置的中断向量,比如EXTI0_IRQn,不同的中断向量我们在stm32f10x.h这个文件中可以找到。

  NVIC_IRQChannelPreemptionPriority :配置相应中断向量抢占优先级。

  NVIC_IRQChannelSubPriority :配置相应中断响应优先级。

  NVIC_IRQChannelCmd :使能或关闭响应中断向量中断。

2、对于中端配置主要的内容是配置中断优先级,stm32有两种中断优先级,我们该怎么配置呢?

中断向量有两个属性,抢占式优先级和响应式优先级,编号越小,优先级越高。当两个中断抢占式优先级相同,则响应式中断优先级高的先执行。

3、NVIC中断优先级组

NVIC只可以配置16种中断优先级,也就是说抢占式优先级和响应式优先级由四位数字来决定,总共可以有5种配置方式,在misc.h文件中我们可以看:

stm32之中断配置

stm32的所有GPIO口都可以配置为EXTI外部中断模式,来捕捉信号,可以上升沿检测,下降沿,上升沿下降沿检测。PA0~PG0连接到EXTI0,PA1~PG1连接到EXTI1,PA2~PG2连接到EXTI2等

三、中断程序编写

我们需要自己建一个.c和.h文件来写中断配置这一块的代码。配置NVIC和中断函数如下所示:

static void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;            //NVIC_InitTypeDef这个结构体我们在misc.h文件中可以找到
  /* Configure one bit for preemption priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);        //配置为第2种中端配置方式,即1bits配置抢占式,3bits配置响应式,这个函数在misc.c文件中,组别在misc.h文件中
  /* 配置中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;       //外部中断0用这种表示方法,中断0~4表示方法都类似,中断5~9表示方式统一为EXTI9_5IRQn,中断10~15统一为EXTI15_10IRQn
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式优先级0
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;     //响应式优先级0
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //使能中断
  NVIC_Init(&NVIC_InitStructure);
}
void EXTI_PA0_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;          //这个结构体在stm32f10x_exti.h中有定义
    /* config the extiline clock and AFIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);                                 
    /* config the NVIC */
    NVIC_Configuration();
    /* EXTI line gpio config*/ 
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;      
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;          // 上拉输入
      GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* EXTI line mode config */
      GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_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);
} 

中断配置完了以后就要真正写代码了,我们的中断处理函数都写在stm32f10x_it.c文件中,示例代码如下:

void EXTI0_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line0) != RESET) //确保是否产生了EXTI Line中断
    {
        // LED1 取反     
        LED1_TOGGLE;
        EXTI_ClearITPendingBit(EXTI_Line0);//清除中断标志位
    } 
}

本文转载自: xtusir

围观 4
37

所有的中档系列PIC单片机,PORTB端口最高的4个引脚(RB7~RB4)在设为输入模式时,当输入电平由高到低或由低到高发生变化时,可以让单片机产生中断。这就是通常所说的引脚状态变化中断。

在设计引脚中断程序时,有三个需要特别注意的地方。

一是,在清除P0RTB中断标志位RBIF之前,必须安排一条必不可少的,以PORTB端口数据寄存器PORTB为源寄存器的读操作指令。放置这一指令的目的有时并不只是为了读取有用的数据,而是为了取消状态变化的硬件信号,以便顺利清除RBIF标志位,为下一次中断做好准备。

二是,由于端口PORTB是引脚电子变化中断,即无论引脚出现上升沿还是下降沿都会产生中断请求,所以必须处理好不需要的虚假中断。

三是,一般都利用PIC单片机的引脚功能来检测按键,所以必须处理好按键消抖的问題。

在主程序里先设置有关的寄存器。

◇设置TRISB寄存器,使RB7~RB4相关的引脚处于输入状态;

◇如果需要弱上拉,通过OPTION_REG的第7位设置;

◇RBIF=O;

◇RBIE=1;

◇GIF=1。

响应状态变化后的中断服务程序。

◇检查RBIF是否为l,为l则是引脚变化引起的中断;

◇调用延时程序,延时20~30 ms,目的是为了按键去抖;

◇判断是引脚出现上升沿还是下降沿引起的中断;

◇调用按键处理程序;

◇读PORTB口的值,取消状态变化的硬件信号;

◇清除RBIF标志。

笔者认为上面程序设计最大的问题是在中断程序里调用延时程序。大家知道,中档PIC单片机只有8层深度的硬件堆栈,在中断里调用于程序出现极易堆栈溢出的情况。另外,PIC单片机中断程序人口只有一个,在响应中断的请求时,PIC单片机就会自动把全局中断的使能位(INTCON的第7位GIF)清除,这样其他中断就暂时不能被响应(此时,如果别的中断发出的中断请求,标志位将一直保留着),直到这个中断程序退出后才会得到响应。这就要求我们设计中断程序的时候必须尽量短,避免调用子程序,更不要在中断里进行复杂的运算。

下面给出笔者设计程序时的思路。

当引脚状态变化引起中断时,在中断子程序里首先判断引起中断的原因是不是我们需要的变化引起的中断。如果是,不要在这里延时,而是设置一个标志位,接着清除中断标志,退出中断。中断程序如下:

else if((RBIE&RBlF)==1){ //如果引脚变化引起中断

if(RB4==0){ //RB4上的按钮接地

key=1; //按键标志位置位

}

RBIF=0; //清除引脚中断标志位

}

其中,if(RB4==0)语句相当于读取了PORTB端口数据寄存器,取消了状态变化的硬件信号。

下面详细介绍怎么样进行按键去抖。

首先,在定时器中断里设置一个lms的时间基准标志位“SYSlms”,每到lms,“SYSlms”便置位。程序如下:

unsigned char count;

if((ToIE&TOIF)==1){ //定时器中断

TMRO+=0x09; //每250μs中断一次

if(count==4){

count=0;

SYSlms=l; //系统时间标志

couot++;

}

T0IF=0; //清除时钟中断标志位

}

有了这个时间基准,便可以在主程序里进行按键去抖处理了。为了更好地利用这个时间基准,定义一个消息标志SYSTime,笔者把它称作时间消息。为了让这个消息有自我发布和自我消失的功能.定义了如下一个宏:

bit SYSTime;

#defincTimeEnahle()SYSTime=0,if(SYSlms){SYSTime=l;SYSlms=0;)

可以把TimeEnable()放到主程序死循环的任何地方,每当程序执行这个宏,SYSTime就会清零,这就是标志位的自我消失.如果在定时器时间基准标志位SYSlms已经置位的话,SYSTime就会置1,这样别的程序就可以利用这个时间消息了,这就是消息的自我发布。下面就是利用这个时间消息来进行按键延时去抖的,首先看一下按键扫描子程序;

void seaakey(){

unsigned char KeyTime,KeyTask;//定义任务时间参数、

//任务参数

switch(KeyTask){

case0:if(key){

KeyTime=30; //准备延时30 ms

KeyTask++; //准备好下一个任务

kcy=0;

}

break;

case I:KeyTime--; //延时30 ms

if(KeyTime==0)Key+ask++;

break;

case2;if(RB4==o){

//调按键处理程序

KeyTask=0;

}

else KeyTask=0;//退出任务

break;

}

}

在主程序的死循环中这样用:

while(1){

TimeEnable();

If(SYSTime==1){scankey();)

//在此可以添加其他程序

只有有时问消息的时候才执行按键扫描程序。可以看到,进入扫描程序执行第一次的时候,程序首先判断按键标志位有没有置位,置位的话(也就是有按键按下的话),任务时间参数(KeyTime)赋值为30,这是延时30ms,去抖,当然你也可以设置为其他的时间值;同时任务参数 (KeyTask)加1。1ms后,再进入扫描程序,这个时候扫描程序执行casel的语句,这样30次后(延时了30ms),任务参数(KeyTask)加1,值为2。lms后,再进入扫描程序,将执行case 2的语句,首先在这里再次判断是不是按键还在按下,如果是就调按键的处理程序,如果不是。就退出按键扫描程序。在这里,还可以加入按键是否抬起的判断程序。

这样设计的引脚变化程序,CPU开销小,效率高,不会出现堆浅溢出的问题,提高了系统的实时性。

来源:畅学电子网

围观 6
95

一、比较器简介

在实际应用过程中有时候我们需要去判断两个变化的电压大小,在不同变化时需要做出不同的反应,这时候我们就可以用到比较器。MM32系列芯片内嵌两个通用比较器COMP1和COMP2, 比较器为通用的可编程电压比较器,支持两个独立的比较器。可独立使用(适合所有终端上的I/O),也可与定时器结合使用。它们可用于多种功能,包括:
• 由模拟信号触发低功耗模式唤醒事件
• 调节模拟信号
• 与 DAC 和定时器输出的 PWM 相结合,组成逐周期的电流控制回路

本文主要介绍一下如何通过比较器产生中断。

二、比较器功能描述

1、比较器输入输出介绍:

比较器框图如下,以COMP1为例,从图中可以看出PA0 – PA7口可连接到比较器的正向输入端,PA4 - PA7口及内部参考电压和三个等分电压值(1/4, 1/2, 3/4)可连接到比较器的反向输入端。比较器输入的 I/O 引脚必须在 GPIO 寄存器中设置为模拟模式。输出端可以重定向到一个 I/O 端口或多个定时器输入端,从而触发不同事件。

MM32如何使用比较器产生中断

2、 比较器时钟:

COMP 时钟控制器提供的时钟与 PCLK 同步(APB2 时钟)。在使用比较器之前,要先使能 RCC 控制器中的时钟使能控制位。

3、 比较器的中断:

比较器的输出可以内部连接到外部中断和事件控制器。每个比较器有自己的 EXTI 信号,能产生中断或事件。COMP1对应外部中断线19,COMP2对应外部中断线20。

4、 功耗模式:

在具体应用中可以通过调整比较器功耗和响应时间得到最优的结果。

COMPx_CSR 寄存器的 MODE[1: 0]位有下面几种设置:
• 00:高速/高功耗
• 01:中速/中等功耗
• 10:低速/低功耗
• 11:极低速/极低功耗

5、 比较器锁定机制:

比较器能用于安全的用途,比如过流或者过热保护。在某些特定的安全需求的应用中,有必要保证比较器设置不能被无效寄存器访问或者程序计数器破坏所改变。为了这个目的,比较器控制和状态寄存器可以设为写保护(只读)。一旦设置完成, LOCK 位必须设为 1,这导致整个 COMPx_CSR 寄存器变成只读,包括 LOCK 位在内。写保护只能被 MCU 复位所清除。

6、 迟滞现象:

比较器的可配置迟滞电压能防止无效的输出变化产生的噪声信号。在不需要强制迟滞电压的情况下迟滞现象可以被禁止。通过配置COMPx_CSR 寄存器 HYST[1:0]可以设置比较器迟滞电压。

MM32如何使用比较器产生中断

比较器的迟滞现象如下图:
MM32如何使用比较器产生中断

三、比较器触发中断实验主要代码分析

本实验以MM32L073为例,比较器配置代码如下图:

MM32如何使用比较器产生中断

中断配置及中断服务子函数如下图所示:
MM32如何使用比较器产生中断

四、实验结果

理论分析:使用信号发生器通过PA1输入频率为1Hz,高电平1.2V,低电平0V的方波,在输入信号由低电平变化为高电平(大于1/4Vrefint)时比较器会产生一个上升沿信号输出高电平,在输入信号由高电平变化为低电平(小于/4Vrefint)时比较器会产生一个下降沿输出低电平,由于设置的外部中断为上升下降沿触发,所以Led会以每0.5S翻转一次。

实验现象:LED以0.5s闪烁,可以通过示波器观察时间,与理论分析符合。

转自: 灵动MM32

围观 8
508

ARM中有5种异常模式,有7种中断源。这7种中断源中有些中断是我们希望发生的,但有些中断是我们不希望发生的。

我们希望发生的中断:

软中断:属于svc模式,通过SWI指令便可以产生软中断,进入到svc模式。

irq中断:属于irq模式,当产生普通的外部中断时,处理器便进入到IRQ模式。

fiq中断:属于fiq模式,当产生高优先级外部中断时,处理器便进入到FIQ模式。

我们不希望发生的中断:

复位:属于svc模式,当系统上电时便会产生复位中断,系统进入到svc模式。复位中断不需要中断返回。

取指中止中断:属于abt模式,当预取指发生错误时,便产生取指中止中断,进入到abt模式。

数据中止中断:属于abt模式,当访问数据存储器时,便产生数据中止中断,进入到abt模式。

未定义指令中断:属于und模式,当执行到一条未定义指令时,便产生未定义指令中断,系统进入到und模式。

中断的优先级:

ARM中有6个优先级。各个中断的优先级顺序如下:(1 6 6s 5 2 4 3)

复位: 1
数据中止中断:2
fiq中断:3
irq中断:4
预取址中止中断:5
未定义指令中断和软中断:6

关于各种中断在中断返回时还需要给LR减去一个不同的偏移量的问题我觉得没必要深入研究了,这还要涉及到ARM指令的流水线技术,平时写中断代码都是用C写的,没必要知道这个。用到时再去查表即可。

ARM中的异常和中断

处理器在进入异常和退出异常时所做的工作:

进入异常时:

1、将要返回处的地址保存在对应异常模式的LR中。(复位不需要保存返回地址)
2、将cpsr的内容复制到对应异常模式的spsr中。
3、强制修改cpsr的内容,进入到相应异常模式以及根据需要修改某些位。
4、强制PC从相应的中断向量地址处进行取址。

注:以上这些步骤都是有cpu自动完成的,也就是当有中断产生时,硬件就会自动完成上述步骤。

退出异常时:

1、将LR中保存的地址赋给PC。
2、将spsr的内容恢复给cpsr。
3、将irq中断禁止位清零。

注:只需要在异常处理程序中写一句返回指令(如上面的表4.1所示)即可全部实现上述的步骤。

转自: frank_yxs

围观 7
946

ARM单片机是大多数新手选择的入门切入点,但由于知识的不足,在设计过程中新手们经常会遇到这样或那样的问题,ARM异常中断返回就是这样一种令人头疼的问题。在ARM的使用问题中异常中断返回是新手们较为苦恼的问题,本文就将对ARM异常中断的集中情况进行总结,并给出了一些解决方法。

在正式介绍之前,要为大家补充一些较为重要的基础知识。首先R15(PC)总是指向“正在取指”的指令,而不是指向“正在执行”的指令或正在“译码”的指令。一般来说,人们习惯性约定将“正在执行的指令作为参考点”,称之为当前第一条指令,因此PC总是指向第三条指令。当ARM状态时,每条指令为4字节长,所以PC始终指向该指令地址加8字节的地址,即:PC值=当前程序执行位置+8;而ADS中的pc,是为了调试看着方便而修改过的,它指向的是正在执行的指令,即“真正pc-8”!

SWI和未定义指令异常中断的返回

指令地址:

A PC-8当前指令为SWI或未定义指令,此时发生中断.PC的值还没有更新。

A+4 PC-4中断时处理器将PC-4保存到LR。;r!

A+8 PC

返回时,从发生中断的指令A(PC-8)的下一条指令A+4(PC-4)处开始执行,所以直接把LR的值赋给PC就行了,具体指令为MOV PC,LR(PC=A+4=LR)。

白话解释:对于SWI和未定义指令发生异常时pc没有更新,根据ARM的三级流水线原理,pc没有更新,仍然等于(A+8);lr = pc – 4(这时处理器决定的,无法更改!)即A+4。

由于这类异常返回后应执行下一条指令(A+4),所以返回时,pc=lr即可。

IRQ 和FIQ异常中断处理的返回指令地址对应于PC A,PC-8执行此指令完成后(!)查询IRQ及FIQ,如果有中断请求则产生中断。

A+4 PC-4

A+8 PC ;lr!

(此时PC的值已经更新,指向A+12.将当前PC-4,即A+8)。

保存到LR.返回时,要接着执行A+4(LR-4)处的指令,所以返回指令为:

SUBS PC,LR,#4(PC=A+4=LR-4)

白话解释:对于普中断和快中断异常,中断必须在一条指令执行完以后被检测到,如正在执行指令甲时发生了中断,不等指令甲执行完是不会处理该中断的,发生异常时pc已经更新(A+12); lr=pc– 4(这时处理器决定的,无法更改!)即A+8返回后,应执行被中断而没有执行的指令(上面的A+4),所以返回时,pc= lr-4。

指令预取中止异常中断处理的返回

指令地址:

A PC-8 执行本指令时发生中断,A+4 PC-4处理器将A+4(PC-4)保存到:

LR. ;lr!A+8 PC

返回时,发生指令预取中止的指令A(PC-8)处重新执行,所以返回指令为SUBS PC,LR,#4(PC=A=LR-4)。

白话解释:对于预取指令中止异常发生预取指令异常时,是在执行时发生的异常,pc未更新,即pc=A+8;lr=pc – 4(这时处理器决定的,无法更改!)即A+4。

由于这类异常返回后应重新执行异常的那个指令(A),所以返回时,pc = lr-4。

数据访问中止异常中断处理的返回

指令地址:

A PC-8 本指令访问有问题的数据,产生中断时,PC的值已经更新。

A+4 PC-4 中断发生时PC=A+12,处理器将A+8(PC-4)保存到LR.。

A+8 PC ;lr!

返回时,要返回到A处继续执行,所以指令为SUBS PC,LR,#8.(PC=A=LR-8)

白话解释:对于数据访问中止异常时,是在执行时访问数据错误。

导致的异常,pc已经更新,即pc=A+12。

lr=pc–4(这时处理器决定的,无法更改!)即A+8。

由于这类异常返回后应重新执行异常的那个指令(A),所以返回时,pc=lr-8。

总结

引起PC更新的原因一种是数据中止,还有就是中断了。

中断必须是在一条指令执行完毕后才能被检测到,所以它中断的只是还未执行的那条。指令(pc-8),所以pc=lr – 4;

与中断相同,SWI和未定义指令异常也是返回到下一条指令(pc-4),只是他们在执行时,PC的值并没有更新,所以pc= lr。

预取指令中止异常,也没有发生pc更新,但它还得重新执行发生异常的那条指令,所以pc=lr–4。

数据访问中止异常,发生了pc更新,并且它也需要重新执行发生异常的那条指令,所以pc=lr–8。

通过以上的介绍,可以看到造成单片机中断返回的原因非常多,每种方法的应对方案都不尽相同。在ARM芯片调试过程中遇到中断返回问题的朋友不妨仔细阅读本文,相信会从中找到问题的解决方法。

转自: 玩转单片机

围观 14
872

有客户需要用到MM32L073,需要通过IAP进行固件升级,在FLASH里面要烧录两份代码:一个Boot loader,一个用户应用程序。在开发应用程序时,使用中断函数不能相应中断。

在开发IAP的用户应用程序时,必须得重新映射中断向量表,中断向量表即某个中断服务程序的入口地址的集合。

在Cortex-M3内核的MCU上可以通过设置SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;该寄存器的值来实现中断向量表的重定义。但用户反馈在MM32L0xx系列以Cortex-M0为内核的单片机中却怎么也找不到这个设置中断向量表的寄存器,用户可以通过以下方法来实现中断向量表重定义。

实现方法基本思想:

1、将中断向量表放入到RAM的起始地址(只需要在应用程序中保留RAM起始地址的0x100大小不使用即可)。
2、在bootload中将应用程序的中断向量表从Flash中拷贝到RAM中。
3、设置MM32L073中断向量表位于RAM中。

MM32 IAP中断向量表重定义

0x20000000是SRAM的起始地址,0x08010000是应用程序的起址地址,从0x08010000开始的字节,存放应用程序的中断向量表。

应用程序代码及自身中断矢量表存放在离0X08000000加某个地址偏移量的地方,即从0x08000000+偏移量的地址开始存放APP代码及中断矢量。这个偏移量要大于IAP的程序空间,防止程序覆盖重定义的中断向量表的数据。在本程序中的偏移量为0x10000,即APP程序的起始地址为0x08010000。

当应用程序发生中断时,内核就从地址0x00处的向量表取相应中断的入口地址,即相当于从0x20000000处的向量表取中断入口地址,当然也相当于从0x08010000处的向量表取中断入口地址,然后去执行相应中断程序。

可以根据startup_MM32L0xx.s的中断函数的入口地址数计算需要预留的空间大小。

MM32 IAP中断向量表重定义

如上图所示,每一个DCD都代表一个中断向量。
例如:
DCD WWDG_IRQHandler ; Window Watchdog
“WWDG_IRQHandler "其实就是WWDG中断服务函数WWDG_IRQHandler的入口地址。

中断向量的集合定义了一张中断向量表,这张表包括48个元素,每个元素是一个长度为4字节的地址。除了第一个地址是SP(堆栈指针)外,其它的地址都是某个中断服务程序的入口地址。中断向量表的所占内存大小为48*4=180(0xC0)个字节。

转自: 灵动MM32

围观 17
902

MCS—51系列单片机内部只有两个外部中断源输入端,当外部中断源多于两个时,就必须进行扩展,下面介绍两种简单的扩展方法:

一、采用硬件请求和软件查询的方法:

这种方法是:把各个中断源通过硬件“或非(高有效,如CD4002)”(与,低有效)门引入到单片机外部中断源输入端(INT0或INT1),同时再把外部中断源送到单片机的某个输入输出端口,这样当外部中断时,通过“或非”(与)门引起单片机中断,在中断服务程序中再通过软件查询,进而转相应的中断服务程序。显然,这种方法的中断优先级取决于软件查询的次序。其硬件连接和软件编程如下:

Void zhongduan (void) interrupt 0 using 3 //中断函数

{

EX0=0;//关中断

If(P0_0=1) { *****}//中断查询

If(P0_1=1) { *****}//中断查询

If(P0_2=1) { *****}//中断查询

EX0=1;开中断

}

二、用普通二极管构成中断选择

单片机扩展中断的4种方法

扩展的8个外部中断源均通过二极管向I N T(x=0或I)请求中断。当某个外部中断源请求中断服务时输出低电平,单片机的I NT 经二极管接地电平,单片机满足响应外部中断(I N T)请求条件,响应中断,程序立即转向I NT 对应的中断入口地址处开始执行中断服务程序,通过软件查询PI.0~P1.7口外中断源的状态,以识别提出请求的外扩中断源,并转向中断服务程序为其服务,其查询顺序即为外部扩展中断源的中断优先级顺序。在图中,是选用PI.0~PI.7作为外扩中断源请求的状态信息输入端口。

有点类似第一种方法。

三、用定时器/计数器作外部中断

单片机的定时器/计数器是一个加一计数器,每当计数输入端有一个“1—0”的负跳变时,计数器加一,当加一计数器溢出时,就向CPU发出中断,利用这个特性来扩展中断的方法是:首先把定时器/计数器设置成计数方式,并预置满值,把外部中断源输入到P3口第4引脚或第5引脚(计数器输入端),这样就可以利用定时器/计数器作为单片机外部中断了。注意这种方法的中断服务的入口地址应在000BH或001BH。

四、用专用中断扩展芯片8259A

8259A是可编程中断控制接口,单片机控制八级中断。在系统中还可采用级联方式,一个主片可级联8个从片,构成64级中断处理系统。

这样在程序小于8K的情况,就可以用一片单片机实现了,而不需要用两片单片机控制,还要进行单片机点对点通讯。

转自 http://www.21ic.com/jichuzhishi/mcu/interrupt/2014-03-20/216130.html

围观 10
460

1 PIC 单片机 简介

PIC系列 单片机 是美国Microchip技术公司推出的高性能价格比的8位嵌入式控制器(Embedded Controller),它采用了精简指令集计算机RISC(Reduced Instruction Set Computer)和哈佛(Harvard)双总线以及两级指令流水线结构。具有高速度、低工作电压、低功耗等特点和优良的性能价格比,因而PIC系列单片机越来越受到单片机开发与应用工程技术人员的青睐。该系列独特的结构和中断资源使其在使用时与其它系列的单片机有许多不同之处。下面以PIC16CXX系列微控制器为例来介绍PIC系列单片机的中断资源特点以及应用方法。

2 中断资源的开发与屏蔽

PIC单片机的中断资源及应用

图1是PIC16C64/64A/65/65A的中断逻辑电路图,其它型号芯睡的中断资源也大致相同,只是资源多少不一而已,但它们的中断入口只有一个(入口地址在004H)。PIC 单片机 的中断大致可以分为两类。
第一类是由中断控制器INTCON直接控制的中断,包括外部引脚中断INT的RB口电平变化中断以及定时器TMRO溢出中断,它们的中断允许位和中断标志都在INTCON寄存器中。引脚中断INT和定时器TMRO溢出中断与其它微处理器相同。RB口电平变化中断是PIC 单片机 特有的中断,当把RB口高4位I/O口线设置为输入时,只要这4位I/O口线上的电平发生变化就会引起中断。RB口的电平中断特性对用户是非常有用的。用户可以直接利用这些口线的关键部位进行电平检测,并可利用中断进行保护性控制等操作;另一方面,电平中断特性还可以利用RB口的软件控制弱上拉特性组成一个矩阵键盘,并用按键唤醒CPU,这对于那些以电池供电的系统特别有用。

另一类是外围接口中断,包括定时器TMR1溢出中断、TMR溢出或匹配中断、同步串行口中断、异步串行口中断、并行从动口中断和CCP(Capture/Compare/PWM)中断等,而带A/D功能的PIC16C7X系列微处理器还有A/D转换完成中断。这些中断的允许位分别在PIE1和PIE2寄存器,而中断标志则分别在PIR1和PIR2中。

所有的中断都有自己的中断允许位和中断标志,外围接口中断不仅受各自的中断允许位控制,同时还共同受外围中断控制允许位的控制。全局中断允许位GID能够控制所有的中断。无论全局中断允许位GIE和相应的中断允许位状态如何,只要满足中断条件,各个中断标志位都会被置1。与其它微处理器不同的是:当CPU响应中断时全局中断允许闰GIF会自动被清零,中断标志位不能用硬件清零而只能用软件清零;当执行中断返回指令RETFIE时,全局中断允许位GIE会被自动置1而重新开放中断。因此,在重新开放中断之前要用软件清零有关的中断标志位,以避免产生不断地中断请求而反复进入中断。由于全局中断允许位GIE会被中断服务程序(RETFIE指令)自动置1,因此用软件清零GIE并不可靠,这一点要特别注意。用下面的程序可确保整个中断被禁止。
***************
LOOP BCF INTCON,GIE ;禁止整个中断
BTFSC INTCON,GIE ;判断全局中断是否被禁止
GOTO LOOP ;否,重新清零
…… ;继续
***************
对于外部中断事件,例如:INT引脚中断和RB口引脚电平变化中断等为边沿触发,因此,CPU在响应中断时对外部信号的要求并不苛刻。一般情况下,中断花费的时间需要3或4个指令周期,确切时间取决于中断事件发生的时刻而与指令本身的周期数无关。

3 中断的优先级

PIC系列 单片机 只有一个中断入口(004H),所有的中断都通过该入口进入中断服务子程序,至于是哪一个中断源,只有在进入中断服务子程序后查询中断标志才能确认。该单片机没规定中断的优先级,也没有用于设定中断优先级的寄存器,中断的优先级是由于中断服务子程序中断查询中断标志的顺序确定的。CPU响应一个中断并进入中断服务程序后,全局中断允许位GIE被自动清零,CPU在此期间不响应其它中断,也不能形成中断嵌套。因此,在使用中断时要合理安排查询中断标志的顺序,尽量缩短CPU在中断服务程序中逗留的时间。在用PIC系列单片机构成系统时应尽量减少中断源的个数,对于那些执行时间较长且不需采用中断方式来处理的事件,应尽量采和查询标志的方式进行处理;对于那些必须采用中断方式处理的事件,在中断服务程序中要尽量先查询对系统至关重要的事件的中断标志。另外,在退出中断服务程序时,只清除处理过的中断标志即可,而不需要将所有的中断标志清除。对于RB口电平变化中断,一方面要保存RB口每次变化后的状态,以便在下次中断时判断是哪根口线上的电平发生了变化;另一方面可以设置产生中断的口线标志,并将由于该中断而未执行的程序在中断服务程序外通过查询口线标志来执行,以减少CPU在中断服务程序中逗留的时间。

4 程序跨页时的中断处理

PIC系列 单片机 的程序存储空间是分页处理的,每页空间的大小为512字节到4k字节不等。页程序计数器PC是一个13位宽的增量寄存器,其低8位PCL是一个可读/写寄存器,其高字节PCH(有效位为5位)不能直接进行读/写操作,它通过一个8位保护寄存器PCLATH把高5位地址传递给程序计数器的高字节。当一个中断被响应时,PC中的断点地址自动被压栈(PUSH)保护;而当执行RETFIE指令时,堆栈中的断点地址回弹到(POP)程序存储器PC中。无论是压栈操作还是出栈操作,它们都不影响PCLATH寄存器的内容。同时,CPU响应中断并跳转到中断入口地址时,都只能在本页内跳转而不影响PLCATH寄存器的内容。另外,在中断入口安排的是GOTO语句,而GOTO语句也只能在本页跳转。当中断服务程序存放在程序存储器的第一页且CPU在执行非第一页内程序时,响应中断将导致中断入口地址和中断返回地址错误而引起程序混乱。下面以PIC16C65A来说明这个问题的解决办法。

PIC16C65A的片内程序存储器为4k,分为两页,每页2k。假设中断服务程序存放在第一页(0000H-07FFH),通常这样做是因为中断入口地址在第一页,因而可以减少程序量)。那么,具体程序如下:

***************
ORG 0000H
0000H GOTO START
ORG 0004H
***************
0004H GOTO PRO-INT
ORG 0005H
0005H START ……
……
0234H PRO-INT……
……
RETFIE
***************

通过汇编程序编译可知,在程序存储器0004H单元存放的代码是2A34H,当CPU在程序存储器第一页响应中断时,程序先跳到0004H,然后跳到0234H执行,正常进入中断,执行完后能正常返回。当CPU在程序存储器第二页响应中断时,由于PCLATH的D4D3(页选择位)为01,CPU4执行“GOTO PRO-INT”时的代码虽然是2A34H,但程序不是跳到0234H执行,而是跳至0A34H执行。显然,程序执行错误。

解决这一问题的方面是在程序存储器0A34H处安排一段程序,在中断程序结束时判断CPU响应中断时程序所处的位置,从而使程序根据该信息合理设置页选择位,然后再返回中断。

******************
ORG 0A34H
BSF RAM,b ;设置在程序执行到第二页时CPU响应中断的标志
BCF PCLATH,3 ;将PC切换到第一页
GOTO PRO-INT ;程序跳转到中断服务程序
*******************
在指令RETFIE前应增加的程序如下:
******************
BTFSC RAM,b ;判断CPU响应中断前程序所在位置
BSF PCLATH,3 ;设置页选择位
RETFIE
******************

以上程序中的RAM是一个内存单元,b是该单元的某一位,该位在程序初始化时清零,CPU在执行程序存储器第二页的程序并响应中断时该位置“1”。经过上述处理,CPU不管在程序存储器第一页还是第二页响应中断,都能正确进入中断服务程序并能正确返回中断前的地址。

5 利用中断唤醒CPU

PIC系列 单片机 具有休眠(SLEEP)省电工作模式,当执行一条SLEEP指令后,芯片就进入低功耗休眠模式。进入休眠状态后,主振荡器停止工作,此时芯片消耗的电流极低(在3V工作电压,32kHz时钟时典型值约1μA),这一特点对于电池供电的系统非常有利。利用中断可以将CPU从休眠状态唤醒。这些中断源包括外部INT引脚中断、RB口引脚电平改变中断和部分外围接口中断。用于唤醒休眠状态的CPU外围接口中断有:工作在异步计数器方式下的TMR1中断、SSP起始/停止位检测中断、CCP捕捉方式中断和从动并行口读写中断。其它外围接口中断因需要片内Q时钟而无法产生中断。

利用中断事件唤醒CPU与全局中断允许位GIE无关,任意一个中断允许位置1的中断源,只要产生中断就会将相应的中断标志置1,芯片将立入中断服务程序与全局中断允许位GIE的状态和紧接SLEEP指令后的那条指令有关。由于PIC系列 单片机 采用了两级指令流水线结构,在执行SLEEP指令时,下一条指令已预先取出,因此在GIE位为0时,芯片被唤醒后首先执行预先取出的那条指令;如果GIE位为1,则芯片被唤醒后执行预先取出的那条指令后紧接着转入中断入口地址再执行中断服务程序。在这种情况下,应在SLEEP指令后安排一条空操作指令NOP,以便CPU被唤醒后能立即进入中断服务程序。

总之,PIC系列单片机 是一种性能价格比很高的微控制器,正确、合理地使用其中断资源可以使系统更加完善,工作更加稳定。

来源: 电子工程世界

围观 21
543

页面

订阅 RSS - 中断