amoBBS 阿莫电子论坛

 找回密码
 注册
搜索
bottom↓
查看: 19283|回复: 112

马老师说:“低优先级别中断可以断高优先级别中断”,我认为不能

[复制链接]
发表于 2007-5-20 19:14:22 | 显示全部楼层 |阅读模式
您说低优先级别中断可以断高优先级别中断,我认为不能。所以请马老师举个“AVR的中断嵌套使用比51复杂些,但它有其本身的优点,你可以实现低优先级中断打断高优先级的中断”例子。

以下蓝色文字由站长:armok 于:2007-10-25,07:04:30 加入。
你的原标题:“<font color=black>关于AVR中断的一个老帖子的疑问
” 不合符规定。请更改成能说明帖子大意的标题
试想一下,如果本论坛的帖子标题清一色的‘帮助!’,‘ADC求救!’等笼统的标题,你在阅读的过程中会造成许多麻烦。
所以本论坛规定:一定要起一个能说明帖子大意的标题。不允许“关于 AVR 的 ADC 使用!”这种笼统标题。作为标题,必须说明清楚:
 ①你是在请教问题,还是在介绍有关的知识?
 ②ADC的问题有许多,你是想说那方面的内容?
注意以上两点,标题应该改成如:“请教:ADC 可以不使用中断吗?”。
起一个能说明帖子大意的标题,除了减轻我们的帖子分类整理工作,还方便其它人阅读,节省大家的时间。
注:使用合格的标题,对你来说只是举手之劳,但却会为我们的管理工作提供很大的便利。谢谢你的支持。
 楼主| 发表于 2007-5-20 19:15:31 | 显示全部楼层
原贴:http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=752781&bbs_page_no=1&bbs_id=1003
发表于 2007-5-21 16:34:59 | 显示全部楼层
你认为不能,那你的理由是什么,你仔细研究和弄明白AVR的中断机制了吗,你有“不能”的例子吗?



你有这样的疑问,首先应该尝试自己去证明,通过仔细阅读器件手册上的说明,然后编写简单的程序验证一下。一味问别人讨程序的话,得不到真正的提高。





提供一个证明和测试的程序



*****************************************************

Chip type           : ATmega16

Program type        : Application

Clock frequency     : 4.000000 MHz

Memory model        : Small

External SRAM size  : 0

Data Stack size     : 256

*****************************************************/



#include <mega16.h>

char count1,count2;



// External Interrupt 0 service routine

interrupt [EXT_INT0] void ext_int0_isr(void)

{

    #asm("sei")                              // 该句删掉和不删掉能证明什么结果?

    count1++;

    PORTA = ~count1;

    while(1)           // 这里是死循环,在中断服务程序中,进入中断后将在这里死等

    {};   

    PORTA = 0xff;

}



// External Interrupt 1 service routine

interrupt [EXT_INT1] void ext_int1_isr(void)

{

    count2++;

    PORTC = ~count2;

}



// Declare your global variables here



void main(void)

{

PORTA=0x0F;

DDRA=0x0F;

PORTC=0x0F;

DDRC=0x0F;

PORTD=0xff;



// External Interrupt(s) initialization

// INT0: On

// INT0 Mode: Falling Edge

// INT1: On

// INT1 Mode: Falling Edge

// INT2: Off

GICR|=0xC0;

MCUCR=0x0A;

MCUCSR=0x00;

GIFR=0xC0;



// Global enable interrupts

#asm("sei")



while (1)

      {

      // Place your code here



      };

}



===========================================



外围连接:

PD2、PD3上为两个按键,并作为中断INT0、INT1的触发。

PA0-4接4个LED,用其表示INT0中断的次数,INT0每中断一次,LED显示加1,用二进制表示。

PC0-4接4个LED,用其表示INT1中断的次数,INT1每中断一次,LED显示加1,用二进制表示。



INT0的优先级高于INT1,当进入INT0中断服务后,由于INT0中断服务中有死循环,所以一但进入INT0中断,就不会退出中断了。此时能不能响应INT1呢?还能不能再次响应INT0呢?



请你自己做全面的测试。最后希望你能给出一个完整的报告,并说明一下我的结论是否正确。
 楼主| 发表于 2007-5-21 21:31:48 | 显示全部楼层
握,明白了,原因是因为AVR的特性,AVR只要进入中断,CPU自动的去掉相应中断的标志位(这要求中断信号不是电平信号),所以在  while(1)           // 这里是死循环,在中断服务程序中,进入中断后将在这里死等

    {};  里面的时候中断标志位一个也没有(相当于没有在中断程序中运行),这时候如果来一个中断,无论什么级别的,都会响应。。

  但是也有一个问题:如果高优先级中断的信号是低电平信号的(进入中断后,CPU不能去掉中断标志),而底优先级的中断,能否打断高优先级别中断了????  

   谢谢马老师费时回答!谢谢~
发表于 2007-5-22 11:21:23 | 显示全部楼层
应该这样理解:



只要全局中断开放,一旦有中断申请,AVR将响应中断的申请,既打断当前正在执行的任何程序(包括正在执行中断服务程序),进入中断服务程序。

如果有多个中断申请同时存在,MCU响应高优先权的中断(回答你的问题)。



========================================================



AVR外部中断的电平触发主要应用于唤醒CPU,其它情况时一般不建议使用电平触发方式。如必须使用电平触发,进入中断后要设法将触发的低电平信号取消,同时电平中断的服务程序中不能再次开放全局中断,否则系统堆栈会很快的爆掉了。



不管是使用51还是AVR,只要采用电平触发方式,那么在进入中断后要设法将触发电平信号取消。如果不取消,51不会爆堆栈(自己不能打断自己),但每次中断退出,又进入了。AVR的中断服务如果是不允许嵌套的,那么同51类似;而在允许嵌套时,会将堆栈压爆。



AVR的低电平触发中断服务应该这样设计,首先该中断服务不允许嵌套,既不能被任何中断打断。其次设法取消该中断的触发低电平(需要硬件的配合了)。服务程序在执行完相应的处理后,应该循环检测触发信号引脚是否恢复成高电平,恢复高电平后再退出本次中断。



实际上我上面提供的例子中也有这样的问题,如果按INT0的键N次后,系统堆栈就会溢出了。



所以我讲AVR的中断处理比51复杂,虽然非常灵活,但需要设计人员有更高的水平。因此建议一般不要采用中断嵌套的结构。一旦必须使用中断嵌套的结构,你必须精心设计你的系统和中断服务程序。否则出现的BUG非常隐蔽,不容易找到。



在一般场合中,我只是提醒大家尽量不要使用AVR的中断嵌套结构,并不做深入的讨论。因为需要具备一定的基础才能讨论这些问题。你是我碰到的第一位问到更深入层次的使用问题的。



其实,AVR中有许多非常有特色的设计,比如它的USART,在硬件设计上比标准51(这里指标准51,因为现在有很多51兼容的,它是否进行了改进我并不能全部了解)的方便使用,而且可靠性也要高多了。你有兴趣的话也可以做深入比较和分析。
 楼主| 发表于 2007-5-22 17:01:17 | 显示全部楼层
谢谢马老师耐心解答!
发表于 2007-8-15 21:37:25 | 显示全部楼层
应该这样理解:



只要全局中断开放,一旦有中断申请,AVR将响应中断的申请,既打断当前正在执行的任何程序(包括正在执行中断服务程序),进入中断服务程序。

*****************************************************************************

但是在马老师的第七章《中断与中断系统》讲义中所说如下:

按照通常的规则,当MCU正在响应一个中断B的过程中,又产生一个其它的中断A申请时,如果这个新产生中断A的优先级比正在响应的中断B优先级高的话,就应该暂停当前的中断B的处理,转入响应高优先级的中断A,待高优先级中断A处理完成后,再返回原来的中断B的处理过程。如果新产生中断A的优先级比正在处理中断B的优先级低(或相同),则应在处理完当前的中断B后,再响应那个后产生的中断A申请(如果中断A条件还成立的话)。



我有点不大明白,请马老师指点!!!
发表于 2007-8-15 21:42:09 | 显示全部楼层
是不是讲义所说有错?我觉得“只要全局中断开放,一旦有中断申请,AVR将响应中断的申请,既打断当前正在执行的任何程序(包括正在执行中断服务程序),进入中断服务程序。”理解没问题!!
发表于 2007-8-23 17:58:57 | 显示全部楼层
6楼:



前面介绍的是通常规则:高优先级中断打断低优先级中断,反之不行,如8051,自动形成中断嵌套。(作为教材,先介绍复习通常的概念)。



后面,我专门讲AVR的中断不是按通常规则办理的,不能自动形成中断嵌套(在黑框中的文字)。



在第7章中,考虑刚开始介绍中断,没有深入介绍AVR的中断嵌套如何处理,在17章的提高和实战单元专门有一节的介绍。“只要全局中断开放,一旦有中断申请,AVR将响应中断的申请,既打断当前正在执行的任何程序(包括正在执行中断服务程序),进入中断服务程序。”



在这个问题上,目前国内80%的AVR的书给出了错误的概念!(尽管AVR的书不多)
发表于 2007-10-24 22:22:07 | 显示全部楼层
搂主真细心亚!
发表于 2007-10-25 06:54:28 | 显示全部楼层
谢谢马老师的耐点解答!!
发表于 2007-10-25 07:16:19 | 显示全部楼层
谢谢马老师的细心解答。COOL !
发表于 2007-10-25 08:31:13 | 显示全部楼层
AVR中断嵌套主要是靠SEI指令实现的,在中断中使用SEI前,一般要把自己现在的中断关闭,以防自己重入自己。
发表于 2007-10-25 09:32:05 | 显示全部楼层
所谓的“通常规则”是以51为参考的,别的单片机也这样吗?
发表于 2007-10-25 12:58:37 | 显示全部楼层
没看过马老师的相关的著作,

我的回答,经过认证的,(全局和各中断都是打开的,在整个过程中没有操作过中断开或关)
1、如果同时多个中断同时发生,首先进入最高级的,
2、如果同时多个中断同时发生,首先进入最高级的,退出最高级中断后,如果其他中断标志位没有去清除,将会依次进入下一个较高级的中断。(如果各层中断开全局中断的话,将使嵌套中断,最终先执行的是最低中断级,然后逐步递进)

另一种情况:
1、进入一个中断,然后打开全局中断和其它中断,在这个中断未退出时,如果存在其它中断,不管中断优先级如何,将会进入新的中断,这种情况我在项目中使用过
例子:使用中断INT0作为按键中断,在中断中加入按键滤波程序,滤波程序主要是使用TIMER0来抗干扰,
程序:
void extern_int1(void)
   {
        EIMSK = 0x00;//        SMCR=0x04;//set sleep mode:power down enable
        if(key1_memory==0)
           {key1_memory=0x088;}
           else
             {;}
    key_check();//调用按键抗干扰
        EIMSK = 0x02;//   }
}
void key_check(void)
{

        unsigned int i;
        unsigned char key_on;
        key_on=key_filter();
       
        switch(key_on)
          {       
            case 0x00:{key_register=0;}break;
            case 0x01:{  
                                 SEI();
                        TCCR0B=0x04;//定时5mS采样   采用定时器来计数按键时间
                           while((PIND&0x08)==0x00)//松开按键                                    {
                                 {
                                if(key_time==0xc8)//3s   采用定时器来计数按键时间
                                {  .............}
                              }
                          ............
                     }break;
                    ..........................
                }
        //return(key_return);
}
void time0_int(void)
   {
     CLI();  //必要的
         TCCR0B=0x00;
         TCNT0=0x29;//15mS
         TCCR0B=0x03;
         if(key_time<0xc8)
            {
              if(((PIND&0x08)==0x00)||((PIND&0x40)==0x00))//PD3(INT1)引脚
                 {
                      key_time++;//key_sw1
                      }
                    else
                      {;}
                   }
                else
                  {TCCR0B=0x00;}
         SEI();  //必要的
         }
51的中断机制不同,可以设定优先级,就是在中断中打开中断,低级别的中断时无法中断高级别的中断的!

关于AVR 的中断机制和操作,在05年深圳 ATMEL 会上曾经问过香港的技术支持和现场的 ATMEL 原厂人员 ,得到的回答不明确,
他们叫俺给E-mail给 ATMEL 的技术员,可惜俺的英语水平不眨的,也就算了,
回来自己调试!

其实可以自己编写一个来试试的,比如在某个中断里 无限循环,然后产生另一个中断,就可以得到答案了!
发表于 2007-10-25 19:16:52 | 显示全部楼层
中断在单片机系统中有非常重要的地位,但也是容易出问题的地方,涉及到很多的方面,如:芯片本身的中断控制机理、中断向量、断点保护、现场保护、优先级、中断嵌套等等。必须在非常明了和清楚的基础上,才能应用好中断系统。

在AVR的数据手册中,当然有对中断的介绍,但作为数据手册,并不会做更多详细的解释。另外,在数据手册中,中断在各个功能模块中都有,分散在各个部分,所以不仔细通读的话,往往不能得到一个真正总体的认识。另外,大家不要用51的中断方式来套AVR,这是非常重要的。

因此,在我书的第7章中,对中断的概念、功能,以及AVR的中断系统和中断控制都做了详细的介绍,大家应该静下心来,仔细的学习一下。还有,由于本书是教材,是针对初学者的,所以在第7章中我提出了尽量不要采用嵌套中断的说法,这也是建立在两个条件之上的:一是AVR的速度快,二是中断服务程序要短。在后面的章节中逐渐加深了中断的应用,如11章中就有嵌套中断的例子,而在17章中则对中断设计的应用做了更深入的说明。

现在这个以前的帖子又被顶了上来,这是一个好的现象,说明有更多的人不是局限于要个程序和算法,而是从根本上去学习、掌握中断的应用。下面对于几个新帖做如下解释。

【12楼】 david1234:AVR中断嵌套主要是靠SEI指令实现的,在中断中使用SEI前,一般要把自己现在的中断关闭,以防自己重入自己。
解释:
    这个说明非常含糊,不明确,有些概念需要进一步的了解。
1。原话“AVR中断嵌套主要是靠SEI指令实现的”,应该是“要实现AVR的中断嵌套,主要是靠在中断服务程序中,再次使用SEI指令实现的”。

2。原话:“在中断中使用SEI前,一般要把自己现在的中断关闭,以防自己重入自己”,容易使人误解。什么叫“把自己现在的中断关闭”,这个概念不明确。AVR的中断控制为三级:全局中断允许位 and 本中断允许位 and 本中断标志位,另外AVR的中断分成可挂起中断,和不可挂起中断。那么应该怎样处理才叫“把自己现在的中断关闭”呢?

【13楼】 xiaobendan:所谓的“通常规则”是以51为参考的,别的单片机也这样吗?

我的原话是:“前面介绍的是通常规则:高优先级中断打断低优先级中断,反之不行,如8051,自动形成中断嵌套。(作为教材,先介绍复习通常的概念)。”
    这里的通常规则,是指比较多的中断处理芯片的采用的基本方式。MCS-51是这样的,另外学习8086课程中的8259的基本方式也是如此,但8259的中断控制比51和AVR都强大的多,中断的优先级可以轮转、排队等等。在正规大学的电子专业教学中,计算机原理应该是一门重要的基础课程,尽管8086、8259现在可能没有人使用了,但基本的思想是非常的重要!可惜,大部分的学生根本没学好,或已经还给老师了。还有,现在的年轻教师可能自己也搞不清楚。
    其实,不同的芯片,其中断机制也有不同和变化。如PIC单片机的中断机制与51和AVR都有区别。因此,掌握中断的基本概念是非常重要的,也只有在这个基础上,当你接触到新的芯片,看了它器件手册,才能很快的了解、掌握和正确的使用这个芯片的中断使用。

【14楼】 cocalli
1。“没看过马老师的相关的著作”,这无关紧要。AVR不是我设计的,我也是看数据手册的,大家根据理解进行讨论吗。

2。14楼的帖子中几点说明都是正确的,大家应该向14楼的学习,尤其是他认真钻研的态度。另外,在众多关于AVR的回贴中,14的帖子是我看到的为数不多的、最好的关于AVR本身应用问题的回贴之一了。

3。“关于AVR 的中断机制和操作,在05年深圳 ATMEL 会上曾经问过香港的技术支持和现场的 ATMEL 原厂人员 ,得到的回答不明确,
他们叫俺给E-mail给 ATMEL 的技术员,可惜俺的英语水平不眨的,也就算了”

    我接触过国内ATMEL很多的代理商和技术支持人员,怎么说呢?只能这样讲:反正14楼去做这个工作的话,在技术上应该可以做到最好。社会的原因我就不讲了。还有一个原因,就是很多写书的人也没搞清楚(很多写AVR书的人,实际上原来是搞51的,对AVR没有做深入的研究,认为把51的东西简单换成AVR就行了)AVR的中断机制,在书中提出了错误的观点,或者根本不提这个问题,混了过去。我接触过设计AVR的国外工程师(国内做技术推广),他们对国内AVR代理商下面的FAE根本看不起,要知道,这些人的水平根本无法与国外的工程师讨论比较深入的问题,在培训现场(就在我们系的AVR实验室)我都感到汗颜,可我也不好说什么,总不能丢中国人自己的脸吧。
    至于香港工程师,技术比内陆人还要差!
发表于 2007-10-25 22:55:20 | 显示全部楼层
呵呵!谢谢马老师的赞扬!

我是从51出来的,那时对51的内核分析的比较透,所以现在学习使用Pic AVR 等都喜欢分析各个单元的工作原理,

当然,我并不是对各个单元都熟悉,一般我都是根据项目的需要才会去分析他,要不然,我一般是了解一下就行!

用到那个模块就必须分许透,要不然使用起来感觉就不是很顺手,

再者,如果有怀疑,可以直接求证,其实是很简单的,稍微修改程序就可以达到目的!
发表于 2007-10-26 14:27:24 | 显示全部楼层
马潮老师:

您好! 对於你那番话: ”至香港工程师,技术比内陆人还要差!”有以下见解.

在客观条件下,香港没有发展技术的良好环境,相反地十分注重销售及市场管理等. 许多香港代理的FAE实际上没有多大机会做开发,我十分怀疑那班代理的FAE究竟编写过多少过AVR程序. 老实说精通AVR对於香港代理们说是意义不大的.

回想十多年前香港Motorola负责研发32位MCU "Dragonball" 龙珠芯片,占了32位MCU十分大的市场份额.但自从研发中心在2001年搬到内地之後,香港Motorola下岗了近千人,香港的IC design及产品应用基础差不多完全真空了. 现在香港祗有零星的小公司,还生存下来的都倾向做QA,采购,商务推广等等. 香港的电子工程师数目相信是深圳1%也没有.

在这些条件下,香港想搅好技术是十分艰难.

不过有部分直属於原公司的FAE,技术方面还不错的.有不少是来自少林寺”香港Motorola”的.
发表于 2007-10-26 16:28:21 | 显示全部楼层
to 17 楼:

我同意你的观点。香港人在对外的合作、语言、管理、市场、资金方面有他们的优势,另外,香港是免税港,有它的历史和地理优势。所以,他们开公司,做生意。而技术支持就移到了内陆,内陆的工程师为他们打工,另外内陆的工资有便宜。

我说的是普遍的状况,香港本地当然也有非常好的工程师。我说介绍的情况,都不是绝对的,是指通常情况下。我结识过几个香港的朋友,都是管理层的。原来本科读的是IT,后来读MBA,转管理了,工资高。他们对技术知道些前沿和发展的东西,对决不精通。但他们捕捉市场的能力、和英语的能力非常好。这些是内陆工程师所缺乏的。
发表于 2007-11-4 12:26:22 | 显示全部楼层
LZ是爱思考的人。
发表于 2007-11-20 21:22:35 | 显示全部楼层
4.AVR中断嵌套处理是通过软件方式实现的。如在B中断服务中,如需要MCU能及时的响应A中断(不是等本次中断返回后再响应),B中断的服务程序应这样设计:(1)B中断的现场保护;(2)屏蔽除A以外其它的中断允许标志;(3)用指令SEI开放允许全局中断;(4)B中断服务;(5)用指令CLI禁止全局中断(6)恢复在本中断程序被屏蔽的中断允许标志;(7)B中断现场恢复;(8)B中断返回。
以前马老师也讲得满清楚的啊
发表于 2007-11-22 14:08:53 | 显示全部楼层
也就是说,avr中断,如果不是同一优先级的多个中断同时发生,就等同于没有优先级,来了中断标志x,就进入x中断服务程序
发表于 2007-11-22 16:23:55 | 显示全部楼层
21楼,AVR同一个优先级就只有一个中断.下载偶的书看看吧.
发表于 2007-11-23 11:08:00 | 显示全部楼层
呵呵,谢谢马老师,21楼打错了,是“不同优先级的多个中断同时发生”,您的书正在看,不过还没看到这儿
发表于 2007-12-5 14:53:23 | 显示全部楼层
马老师:
全局中断开放,只要有新的中断,AVR都要响应新的中断中级别高的中断。退出中断后,再对所有现存的中断,按级别进入下一个中断。是否可以这样理解。
发表于 2007-12-5 21:20:09 | 显示全部楼层
24楼的理解是正确的.
发表于 2007-12-5 22:46:14 | 显示全部楼层
谢谢,马老师。知道了。
发表于 2007-12-25 21:19:25 | 显示全部楼层
我看完贴后,感到非常激动,学到了不少。试问:这样的好贴不顶起来难道让它沉下吗?
发表于 2008-3-21 19:04:10 | 显示全部楼层
理解了AVR的中断机制,觉得最重要的就是:“全局中断开放,只要有新的中断,AVR都要打断当前正在执行的任何程序(包括正在执行的中断服务程序),去响应新的中断中级别高的中断。”
但是对于“AVR中断的优先级由该中断向量在中断向量区的位置确定”有点困惑,这个跟51不同,请教马老师,AVR内部是怎样实现这个的?
多谢~~
发表于 2008-3-21 20:47:11 | 显示全部楼层
"AVR中断的优先级由该中断向量在中断向量区的位置确定"

这点实际同51是类似的.是由内部的中断控制硬件电路实现.

与51不同的是,AVR的中断优先级不能通过软件设定改变,以及缺省状态不能实现中断嵌套.
 楼主| 发表于 2008-3-21 21:29:16 | 显示全部楼层
.
发表于 2008-3-29 10:57:43 | 显示全部楼层
没看过马老师的书, 在这里小声问一下, 在AVR进中断时, 硬件会清除全局中断使能标志吗?

=====================================================
不看偶的书没什么,器件手册必须要看的.
发表于 2008-4-7 00:24:41 | 显示全部楼层
马老师:DATASHEET只字未提中断优先级 不明白这中断优先级究竟从何而来???
发表于 2008-4-7 01:37:54 | 显示全部楼层
Reset and Interrupt Handling

The AVR provides several different interrupt sources. These interrupts and the separate reset vector each have a separate program vector in the program memory space. All interrupts are assigned individual enable bits which must be written logic one together with the Global Interrupt Enable bit in the Status Register in order to enable the interrupt.
Depending on the Program Counter value, interrupts may be automatically disabled when Boot Lock bits BLB02 or BLB12 are programmed. This feature improves software security. See the section “Memory Programming” on page 262 for details.

The lowest addresses in the program memory space are by default defined as the Reset and Interrupt Vectors. The complete list of vectors is shown in “Interrupts” on page 45. The list also determines the priority levels of the different interrupts. The lower the address the higher is the priority level. RESET has the highest priority, and next is INT0 – the External Interrupt Request 0.

楼上,你看到了吗???
发表于 2008-4-7 13:30:55 | 显示全部楼层
谢谢马老师指点 我看书不精 惭愧惭愧
发表于 2008-5-19 17:11:51 | 显示全部楼层
马老师果然细心呀!!!
发表于 2008-7-28 20:24:20 | 显示全部楼层
好贴 太感谢了马老师了!!
发表于 2008-8-31 11:08:57 | 显示全部楼层
实验做过了,对中断有了更进一步的理解,谢谢马老师。
发表于 2008-11-11 23:41:49 | 显示全部楼层
就AVR要实现中断嵌套过程看,是非常简单的:只要在中断服务程序中打开全局中断允许标志,那么该中断就可以被任何的中断所打断(包括自己本身新产生的中断申请!)。



但是,越是实现简单,使用中却越是复杂,因为留给程序员考虑的东西太多了。一旦考虑不周全就会出问题。因此我讲“尽量”不要使用中断嵌套,除非你有很深的工夫。
发表于 2008-11-12 10:10:36 | 显示全部楼层
看了马老师的帖,我碰到的问题应该就是由于中断嵌套引起的。我使用外部中断,低电平触发,在外部中断服务程序里是这样处理的:

关闭外部中断

打开全局中断允许(为了响应UART接收中断,否则会丢失数据)

外部中断处理程序

打开外部中断



我这样处理在程序运行时间较长的情况下会出现程序跑飞的现象,类似复位现象但是打出MCUCSR值为0.马老师在4楼的帖子说的“AVR外部中断的电平触发主要应用于唤醒CPU,其它情况时一般不建议使用电平触发方式。如必须使用电平触发,进入中断后要设法将触发的低电平信号取消,同时电平中断的服务程序中不能再次开放全局中断,否则系统堆栈会很快的爆掉了。&nbsp;”,我出现的现象应该是马老师说的系统堆栈爆掉了。

决定将中断触发方式改为下降沿触发,应该可以吧,先去测试看看
发表于 2008-11-23 11:21:08 | 显示全部楼层
我也仔细想过中断嵌套的问题,对于马超老师在4楼所说的:“AVR外部中断的电平触发主要应用于唤醒CPU,其它情况时一般不建议使用电平触发方式。如必须使用电平触发,进入中断后要设法将触发的低电平信号取消,同时电平中断的服务程序中不能再次开放全局中断,否则系统堆栈会很快的爆掉了。&nbsp;”这段话,我有不同意见。

我是这样理解的:使用电平触发,只要进入中断后不再次开放全局中断,在中断程序结束前判断低电平信号已变成高电平然后再出中断,也应该是可以的,不需要“进入中断后设法将触发的低电平信号取消”,要取消外部触发低电平大多数情况下是很困难的,特别是在掉电检测中应用,以上请指教
发表于 2008-12-4 14:50:43 | 显示全部楼层
谢谢马老师以及回帖的人
发表于 2008-12-13 13:44:11 | 显示全部楼层
有个现象请大家帮忙解释一下:

在马老师书中第222页,关于外部中断的例子中。

中断服务程序:

interrupt&nbsp;[EXT_INT0]&nbsp;void&nbsp;ext_int0_isr(void)

{

&nbsp;&nbsp;if(++counter>=16)&nbsp;counter&nbsp;=&nbsp;0;

}

大概意思就是:当外部引脚从高电平跳到低电平的时候,触发该中断,此时进入该中断服务程序中,全局变量counter自增1,如果大于等于16,归零,main函数中,把counter值输出到LED数码管显示。



问题:



按键一次,结果出现了“按键两次或多次”的效果。

即:当前显示为:6&nbsp;按键一次后,显示为8,或9.



解释:



由于按键瞬间,电平产生的抖动,于是产生了多个下降沿,相当于多次引发中断。



解决办法:



在原来中断服务程序中加入延时



interrupt&nbsp;[EXT_INT0]&nbsp;void&nbsp;ext_int0_isr(void)

{

&nbsp;&nbsp;delay_ms(100);

&nbsp;&nbsp;if(++counter>=16)&nbsp;counter&nbsp;=&nbsp;0;

}



这样的话在第一个下降沿产生中断后,进入延时代码,在延时过程中,第二个下降沿来临时,由于仍然没有退出中断服务程序,又没有手动打开全局中断变量,所以不会引发中断,因此应该避免电平抖动产生多个中断的问题。



但是通过具体试验证明(亲自在实验版上做的):仍然会出现问题:按一次,数字增加2.但最多就增加2了,不会增加3或更多。



希望大家帮我解释一下原因?马老师,如果您有时间的话,也麻烦您帮我解释一下。
发表于 2008-12-13 16:44:00 | 显示全部楼层
到这里http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=1537837&bbs_page_no=1&bbs_id=1003,看7楼我有一个例子,可以参考一下。
发表于 2008-12-18 22:08:06 | 显示全部楼层
http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=1375867&bbs_page_no=1&search_mode=3&search_text=weixiao361&bbs_id=9999





这里也有马老师的解释哈,





http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=1537837&bbs_page_no=1&bbs_id=1003&nbsp;&nbsp;&nbsp;&nbsp;七楼&nbsp;
发表于 2008-12-28 11:26:47 | 显示全部楼层
马老师的精辟见解要顶!顶!
发表于 2008-12-28 12:24:57 | 显示全部楼层
马老师的确是很厉害的高手哦!看问题全面的很!值得学习!

没有什么常规,各有各的规则!
发表于 2008-12-18 23:07:37 | 显示全部楼层
在原来中断服务程序中加入延时&nbsp;



interrupt&nbsp;[EXT_INT0]&nbsp;void&nbsp;ext_int0_isr(void)&nbsp;

{&nbsp;

&nbsp;&nbsp;delay_ms(100);&nbsp;

&nbsp;&nbsp;if(++counter>=16)&nbsp;counter&nbsp;=&nbsp;0;&nbsp;

}&nbsp;



这样的话在第一个下降沿产生中断后,进入延时代码,在延时过程中,第二个下降沿来临时,由于仍然没有退出中断服务程序,又没有手动打开全局中断变量,所以不会引发中断,因此应该避免电平抖动产生多个中断的问题。&nbsp;



但是通过具体试验证明(亲自在实验版上做的):仍然会出现问题:按一次,数字增加2.但最多就增加2了,不会增加3或更多。&nbsp;

============================================================================================================



道理在这里:



在第一个下降沿产生中断后,进入延时代码(注意,此前清除了中断标志位),

在延时过程中,第二个下降沿来临时,由于仍然没有退出中断服务程序,又没有手动打开全局中断变量,所以不会引发中断====》错!



这第二个下降沿的出现,又把中断标志位被置1了!这个中断申请被挂了起来,尽管此时不会引发,可是当本次中断退出后,由于中断标志位为1,所以还要执行了一次中断。



实际上,下降抖动是多次的,但标志位置1后,再多下降沿也是1,所以最多就是增加2了。



如果你在中断返回前加上一句清除中断标志位的语句,那么就可能不会出现增加2了。为什么是可能?因为如果100ms中没有释放按键,那么释放按键如果产生抖动也会引起中断的。



不过在中断中使用软件延时是不提倡的。关于按键的处理还是不用外部中断的好,本书后面专门介绍了按键的处理方法,真正在系统使用按键应该用后面的方法。这里只是让大家了解外部中断的使用以及体会按键需要削抖。

本贴被 machao 编辑过,最后修改时间:2008-12-19,10:01:59.
发表于 2009-5-11 16:00:35 | 显示全部楼层
第一次响应INT0的时候能不能关闭INT0的中断使能,在中断处理完毕后返回前再开INTO中断使能,这样能不能避免INTO自我嵌套?
发表于 2009-5-22 16:27:25 | 显示全部楼层
好文章,做个记号!!
发表于 2009-5-22 16:58:51 | 显示全部楼层
再次提醒各位,认真学习AVR的中断!

AVR在响应任何中断时,硬件将全局中断关闭了,执行中断返回指令时,自动将全局中断打开。因此确省情况下是不支持中断嵌套的!

使用C语言编写中断服务程序时不要画蛇添足,留下隐患。下面是一个画蛇添足的例子:

某个中断服务函数,不希望被别的中断打断(不支持中断嵌套):

中断服务函数
{
    关闭全局中断;
    。。。。
    服务语句;
    。。。。
    打开全局中断;
}

粗看好象没有问题,进入中断,关全局中断,执行服务,中断返回前打开全局中断。该中断不会被其它中断打断。

其实不然,因为C代码在中断返回前还要加上中断现场恢复的许多指令的,机关从C代码看,打开全局中断后就是中断返回了,其实真正的汇编代码中,在打开全局中断指令和中断返回指令之间,还有许多的中断现场恢复指令,而在执行这些指令时,如果有中断发生,那么就形成了中断嵌套了。

如果中断服务函数不希望被别的中断打断,那么C代码中的“关闭全局中断”和“打开全局中断”根本不需要,写了就是画蛇添足,反而留下隐患。

从这个例子也说明,尽管大家基本上采用C编写代码了,但还是需要真正了解芯片的特点,掌握汇编,了解汇编和C之间的不同。
发表于 2009-5-22 23:29:54 | 显示全部楼层
虽然我现在不是很懂avr,但是看过上面的帖子之后,发现马老师确实是一个非常仔细、认真的人!希望我们大三的avr也是马老师给我们上!
发表于 2009-5-23 21:11:36 | 显示全部楼层
马老师~~  真的很佩服你~~  恩 我会好好学的啊~~~
学好微机打好基础~~~
发表于 2009-9-3 09:24:46 | 显示全部楼层
!
发表于 2010-1-2 01:38:08 | 显示全部楼层
马老师,您研究问题的认真态度,
让学生很感动,也学到很多东西…
发表于 2010-1-4 00:30:16 | 显示全部楼层
看热闹
发表于 2010-1-4 11:02:50 | 显示全部楼层
好帖
发表于 2010-1-6 17:11:17 | 显示全部楼层
中断优先级的判断和执行只是在中断同时发生的那一刻进行。比如两个人去买票,如果排队,不论谁先谁后都是顺序完成;但是如果两人同时争那窗口,很好,现在谁的力气大,谁NB,那就优先买票……这样说应该比较形象吧?
发表于 2010-1-6 19:45:10 | 显示全部楼层
mark
认真学习下
发表于 2010-1-14 08:37:54 | 显示全部楼层
学习
发表于 2010-1-14 12:02:16 | 显示全部楼层
MARK并稍后学习
发表于 2010-1-29 22:59:59 | 显示全部楼层
我斗胆在这里说一句,其实只要我们仔细阅读官方提供的数据手册,基本上大部分关于IC本身的疑问都可以解决的!
发表于 2010-1-30 00:31:00 | 显示全部楼层
留名看懂了再来以后学习
发表于 2010-3-2 14:16:26 | 显示全部楼层
MARK
发表于 2010-4-21 17:57:05 | 显示全部楼层
回复【50楼】machao
再次提醒各位,认真学习AVR的中断!
AVR在响应任何中断时,硬件将全局中断关闭了,执行中断返回指令时,自动将全局中断打开。因此确省情况下是不支持中断嵌套的!
使用C语言编写中断服务程序时不要画蛇添足,留下隐患。下面是一个画蛇添足的例子:
某个中断服务函数,不希望被别的中断打断(不支持中断嵌套):
中断服务函数
{
    关闭全局中断;
    。。。。
    服务语句;
    。。。。
    打开全局中断;
}
粗看好象没有问题,进入中断,关全局中断,执行服务,中断返回前打开全局中断。该中断不会被其它中断打断。
其实不然,因为C代码在中断返回前还要加上中断现场恢复的许多指令的,机关从C代码看,打开全局中断后就是中断返回了,其实真正的汇编代码中,在打开全局中断指令和中断返回指令之间,还有许多的中断现场恢复指令,而在执行这些指令时,如果有中断发生,那么就形成......
-----------------------------------------------------------------------

谢谢马老师,受益匪浅
发表于 2010-6-13 21:58:37 | 显示全部楼层
mark
发表于 2010-7-28 23:16:40 | 显示全部楼层
Mark
发表于 2010-7-29 00:26:10 | 显示全部楼层
强帖留名
发表于 2010-7-29 08:34:34 | 显示全部楼层
mark
发表于 2010-8-16 13:55:50 | 显示全部楼层
学习了~~~
发表于 2010-8-21 16:33:14 | 显示全部楼层
看不明白,等学了AVR再回来好好看。
正愁没老师教呢,我在这找到了好多老师!
发表于 2010-8-23 10:39:28 | 显示全部楼层
强帖。。。mark
发表于 2010-8-23 12:27:08 | 显示全部楼层
非常感谢马老师!
发表于 2010-9-16 09:55:17 | 显示全部楼层
mark 学习一下
发表于 2010-10-9 13:24:57 | 显示全部楼层
mark
发表于 2010-10-9 14:43:21 | 显示全部楼层
mk
发表于 2010-11-1 21:55:50 | 显示全部楼层
这么好的帖子现在才看到,今天对avr的中断算是又有新的理解了!非常感谢马老师!
发表于 2010-11-4 14:50:55 | 显示全部楼层
这么好的帖子现在才看到,今天对avr的中断算是又有新的理解了!非常感谢马老师!
发表于 2011-3-5 10:00:07 | 显示全部楼层
好帖
发表于 2011-3-5 10:40:53 | 显示全部楼层
AVR单片机的RETI指令在执行后就能将I位置位,所以不需要额外的SEI指令。
发表于 2011-3-16 15:44:45 | 显示全部楼层
mark
发表于 2011-4-8 09:23:11 | 显示全部楼层
回复【50楼】machao  
再次提醒各位,认真学习avr的中断!
avr在响应任何中断时......
-----------------------------------------------------------------------

这里出现问题实际上还是因为在真正结束中断服务程序前打开了全局中断,中断的发生是“无孔不入”的,任何一点点机会都可能成为悲剧的开始~而高级语言并不能“事无巨细”,因而出错了。这段代码的风格实际上是延续了51汇编的要求。在51汇编中这两句话是放在中断程序头尾的,但在高级语言中,因为恢复现场的指令由编译软件代为处理,故而程序员理解的离开中断服务程序的时间点与真正意义上的时间点存在差异,正是这个空子被中断抓住了。实际上AVR在进入中断服务程序之后如果不打开全局中断是不会形成中断欠套的,因而无需用前述代码进行保护。不知理解得对吗?
发表于 2011-4-8 12:09:10 | 显示全部楼层
mark
发表于 2011-4-8 12:41:22 | 显示全部楼层
这个问题记得这里讨论过,并且不止一次,好几次都是点名马老师,乍一看标题,感觉不好。

个人觉得,这个小问题,只要编写一个小程序,稍微测试就可以得到结论,
发表于 2011-4-8 12:54:17 | 显示全部楼层
感觉颇深啊!
发表于 2011-4-16 21:52:33 | 显示全部楼层
发表于 2011-4-17 08:31:38 | 显示全部楼层
不错,楼主的精神值得学习
发表于 2011-4-17 10:14:55 | 显示全部楼层
马老师大神~  这个...主要是看看新改的头像怎么样...
发表于 2011-4-25 05:59:41 | 显示全部楼层
"只要全局中断开放,一旦有中断申请,AVR将响应中断的申请,既打断当前正在执行的任何程序(包括正在执行中断服务程序),进入中断服务程序。 "

"(包括正在执行中断服务程序)" --- that's correct and incorrect at the same time but mostly incorrect.

the default interrupt behavior is this:

1) an interrupt flag is set;
2) the mcu jumps to the corresponding isr;
3) the mcu clears the global interrupt bit - disabling all interrupt;
4) save the context and execute the isr;
5) exit the isr - RETI also set the global interrupt bit, enabling all interrupt.

so in the default scenario, the arrival of a new interrupt does NOT interrupt an interrupt in process, regardless of its priority.

be design, this default interrupt handling does not allow nested interrupt - where only a high priority interrupt can interrupt a low-priority interrupt.

this means a few things:

1) you have to explicitly tell the compiler if you need nested interrupt - using the NAKED keyword for gcc-avr or example.
2) you don't need to explicitly disable interrupt in the isr - the hardware does it for you;
3) you don't need to explicitly enable interrupt before existing the isr - the hardware does it for you.
发表于 2011-4-25 06:01:32 | 显示全部楼层
assuming that you did enable nested interrupt, if a new interrupt arrives while another isr is being executed, you have two scenarios:

1) if the new interrupt is of higher priority than the current interrupt, the mcu will execute the new / higher priority isr;
2) if the new interrupt is of lower priority than the current interrupt, the mcu will continue to execute the current isr.
发表于 2011-4-25 06:08:13 | 显示全部楼层
so the only time the original statement is correct is if:

1) the user has enabled nested interrupt, AND
2) the new interrupt is of higher priority than the existing interrupt.

if any one of the two conditions doesn't hold, the mcu will not respond to the new interrupt right away.
发表于 2011-4-25 08:07:07 | 显示全部楼层
中断有三种,Higher priority, same priority and lower priority

Millwood0 你只说明了其中二种的处理。
发表于 2011-4-25 08:54:14 | 显示全部楼层
"中断有三种,Higher priority, same priority and lower priority

Millwood0 你只说明了其中二种的处理。 "

in AVR, each interrupt has an unique priority. so interrupts of the same priority do NOT exist for AVR.
发表于 2011-4-25 09:14:02 | 显示全部楼层
I know each hardware interrupt has an order.

Of course I meant interrupt request to the AVR, not interrupt servicing routine.

In addition, your post on the interrupt handling arrangement is incorrect. AVR is different to 8051 in the aspect of handling interrupt priority.

你对 AVR 的中断安排说明有误。在 【90楼】point(2) 的说明是错的。在使能全局中断後,任何使能的个别中断要求都会/能中断现行程式。只有在多个使能的中断要求下, AVR 才会选用较高 priority 的中断程式。
发表于 2011-5-27 08:46:23 | 显示全部楼层
几点看法
8楼
1)
前面介绍的是通常规则:高优先级中断打断低优先级中断,反之不行,如8051,自动形成中断嵌套。(作为教材,先介绍复习通常的概念)。


我以为这是抄书而不是写书的所致。什么是通常规则?依据是什么?教材教的什么?
高优先级别的要点是在发生的中断请求中,级别高的优先响应,而不是打断低优先级别的中断。既然出现AVR的
的低级别中断可以打断高优先级别的中断,而且教材说的是AVR,明显教材处理是考虑不周,处理不当。
2)
40楼的认识是恰当的。但并不一定要关全局中断,屏蔽该中断也可以,目的是避免堆栈出错。如何运行电平触发,
是每个设计者的根据需要而定,是如何运用的事。
发表于 2011-5-27 13:51:22 | 显示全部楼层
谢谢马老师
发表于 2011-8-5 01:54:57 | 显示全部楼层
谢谢马老师
谢谢cocalli
发表于 2011-8-5 08:44:51 | 显示全部楼层
kankan
友情提示:标题不合格、重复发帖,将会被封锁ID。详情请参考:论坛通告:封锁ID、获得注册邀请码、恢复被封ID、投诉必读
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|阿莫电子论坛(原ourAVR/ourDEV) ( 公安备案:44190002001997(交互式论坛) 工信部备案:粤ICP备09047143号 )

GMT+8, 2019-9-18 03:59

阿莫电子论坛, 原"中国电子开发网"

© 2004-2018 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表