AVR中断应用设计要点
AVR的中断源比较多,尤其是ATmega128,一共有35个外部以及内部中断源。通常情况下,Flash程序存储器空间的最低位置(0x0000-0x0045)定义为复位和中断向量空间。完整的中断向量见第二章表2-23。在中断向量表中,处于低地址的中断向量所对应的中断拥有高优先级,所以,系统复位RESET拥有最高优先级。A.中断设计注意点:
1.具备Bootloader功能的AVR,其中断向量区可以在Flash程序存储器空间最低位置和Bootloader区的头部来回迁移,这主要用于配合Bootloader程序的应用。如果不使用Bootloader功能,一般不要中断向量区进行迁移。
2.Flash较小的AVR芯片,其一个中断向量占据1个字的空间,用于放置一条相对转移RJMP指令(范围-2K~+2K字),跳到中断服务程序。对于不使用的中断,在中断向量区中应放置1条中断返回指令RETI,增强程序的抗干扰性。
3.ATmega128的Flash空间为64K字,因此它的一个中断向量占据2个字的空间,用于放置一条绝对转移JMP指令(指令长度为2个字),跳到中断服务程序。对于不使用的中断,在中断向量区中应连续放置2条中断返回指令RETI,增强程序的抗干扰性。当使用汇编语言编写系统程序时应注意。
4.当MCU响应一个中断时,其硬件系统会自动中断返回地址压入系统堆栈,并将关闭全局中断响应(硬件将中断标志I位清0),清除该中断的中断标志位;执行中断返回指令RETI时,硬件会先允许全局中断响应(硬件将中断标志I位置1),然后从系统堆栈中弹出返回地址到PC程序计数器中,继续执行被中断打断的程序。除此之外,MCU的硬件没有对中断保护做其他处理。
5.因此,用户在编写中断服务程序时,首先要编写中断现场保护程序,如保护MCU的状态寄存器等。在中断返回之前,不要忘记恢复中断现场。
6.如果设置和允许外部中断响应,即使是外部INT0..7引脚设置为输出方式,在引脚上的电平变化也会触发外部中断的发生,这一特性提供了使用软件产生中断的途径。
7.外部中断可选择采用上升沿触发、下降沿触发以及电平变化(由高变低或由低变高)和低电平触发等方式,无外部高电平触发方式。具体触发方式由外部中断控制寄存器EICRA(INT3:0)和EICRB(INT7:4)决定。
8.如果选择外部低电平方式触发中断时应特别注意:(1)引脚上的低电平必须一直保持到当前一条指令执行完成后才能触发中断;(2)低电平中断并不置位中断标志位,即外部低电平中断的触发不是由于中断标志位引起的,而是外部引脚上电平取反后直接触发中断(当然需要开放全局中断允许)。因此,在使用低电平触发方式时,中断请求将一直保持到引脚上的低电平消失为止。唤句话说,只要中断引脚的输入引脚保持低电平,那么将一直触发产生中断。所以,在低电平中断服务程序中,应有相应的操作命令,控制外部器件释放或取消加在外部引脚上的低电平。
B.中断优先级以及中断嵌套处理
1.AVR中断的优先级由该中断向量在中断向量区中的位置确定,处于低地址的中断向量所对应的中断拥有高优先级,所以,系统复位RESET拥有最高优先级。
2.当两个中断同时发生申请中断时,MCU先响应中断优先级高的中断。低优先级的中断一般将保持中断标志位的状态(外部低电平中断除外),等待MCU响应处理。
3.MCU响应一个中断后,在进入中断服务前已由硬件自动清零全局中断允许位。因此此时即使有更高优先级的中断请求发生,MCU也会不响应,要等执行到RETI指令,从本次中断返回,并执行了一条指令后,才能继续响应中断。所以,在缺省情况下,AVR的中断不能嵌套。AVR中断的优先级只是在有多个中断同时发生时才起作用,此时MCU将首先响应高优先级的中断。
4.AVR中断嵌套处理是通过软件方式实现的。如在B中断服务中,如需要MCU能及时的响应A中断(不是等本次中断返回后再响应),B中断的服务程序应这样设计:(1)B中断的现场保护;(2)屏蔽除A以外其它的中断允许标志;(3)用指令SEI开放允许全局中断;(4)B中断服务;(5)用指令CLI禁止全局中断(6)恢复在本中断程序被屏蔽的中断允许标志;(7)B中断现场恢复;(8)B中断返回。
5.采用软件方式实现中断嵌套处理的优点,是能够让程序员可以根据不同的实际情况和需要来决定中断的重要性,有更加灵活的手段处理中断响应和中断嵌套,如让低优先级的中断(此时很重要)打断高优先级中断的服务等,但同时也增加了编写中断服务程序的复杂性。
6.由于AVR的指令执行速度比较高,因此在一般情况下,不建议使用中断嵌套的处理方法。当然,这还需要用户在编写中断处理服务程序中,应遵循中断服务程序尽量要短的原则。
C.高级语言开发环境中中断服务程序的编写
1.在高级语言开发环境中,都扩展和提供了相应编写中断服务程序的方法,但不同高级语言开发环境中对编写中断服务程序的语法规则和处理方法是不同的。用户在编写中断服务程序前,应对所使用开发平台,中断程序的编写方法,中断的处理方法等有较好的了解。
2.使用ICCAVR、CVAVR、BASCOM-AVR等高级语言编写中断服务程序时,通常不必考虑中断现场保护和恢复的处理,因为编译器在编译中断服务程序的源代码时,会在生成的目标代码中自动加入相应的中断现场保护和恢复的指令。
3.如果用户要编写效率更高或特殊的中断服务程序,可以采用嵌入汇编、关闭编译系统的自动产生中断现场保护和恢复代码等措施,但程序员要对所使用的开发环境有更深的了解和掌握,并具备较高的软件设计能力。本人中给出的USART接收和发送中断服务程序(使用CVAVR开发平台)就是一个非常典型的示例。
本文作者:马潮老师
-----此内容被machao于2005-03-07,22:32:46编辑过 非常感谢谢Machao老师,赶快去学习的东东 不知何故马老师从没推荐过GCCAVR,学生我有些晕点... 所以革_命尚未成功,hotpower尚需继续努力推广...
哈哈... 革_命虽未成功,但贿赂了一个王连举一样的站长...
哈哈...没看过样板戏的人是搞不明白的. 晕...
估计这里受过样板戏直接熏陶的大侠屈指可数... 马老师!我看来帖子!觉得在下面的这段话中有些问题!请指点!!!
B中断的服务程序应这样设计:(1)B中断的现场保护;(2)屏蔽除A以外其它的中断允许标志;(3)用指令SEI开放允许全局中断;(4)B中断服务;(5)用指令CLI禁止全局中断(6)恢复在本中断程序被屏蔽的中断允许标志;(7)B中断现场恢复;(8)B中断返回。
就是过程(4) 我觉的应该是A中断服务 吧! 说得不是在B 中断中响应 A 中断吗? 这里指B中断服务程序的编写。在(4)这个过程中,即在整个B的具体中断服务过程中,如果A中断出现,就会暂时打断B的服务程序,执行A中断服务。A中断返回后,再继续执行(4)的B中断服务。这就实现了AVR中断嵌套。 你好:
问一下用GCC要考虑中断现场保护和恢复的处理么?他不会自动生成中断现场保护和恢复的处理么? 凡是采用高级语言开发平台编写中断服务程序,程序员一般均不必考虑中断现场的保护和恢复处理。由编译器自动生成。 B中断的服务程序应这样设计:(1)B中断的现场保护;(2)屏蔽除A以外其它的中断允许标志;(3)用指令SEI开放允许全局中断;(4)B中断服务;(5)用指令CLI禁止全局中断(6)恢复在本中断程序被屏蔽的中断允许标志;(7)B中断现场恢复;(8)B中断返回。
马老师您好!是不是可以这样理解,因为有了(5)这一步,在其后的某一非常短的时间里(即B中断现场恢复的过程中),就不能响应中断A了吧? 是的。 明白了,谢谢马老师! 谢谢马老师! 3.MCU响应一个中断后,在进入中断服务前已由硬件自动清零全局中断允许位。因此此时即使有更高优先级的中断请求发生,MCU也会不响应,要等执行到RETI指令,从本次中断返回,并执行了一条指令后,才能继续响应中断。所以,在缺省情况下,AVR的中断不能嵌套。AVR中断的优先级只是在有多个中断同时发生时才起作用,此时MCU将首先响应高优先级的中断。
马老师,请问这句话怎么理解,在中断服务程序执行的时候又来一个中断请求,是忽略它,还是等中断服务程序执行完后再处理它。 AVR的中断有2种类型的,一种是设置标志位为"1"的可挂起中断,一种是不影响标志位的不可挂起中断.大部分的中断属于第一种形式的.
>>在中断服务程序执行的时候又来一个中断请求........
AVR在进入响应中断过程中,由硬件自动将全局中断允许标志清另,因此在中断服务程序执行过程中是不会再响应其它的中断了,所以后来的中断不会不会马上得到响应.
根据后来中断类型的不同,后续的处理也不一样:
如果是第一类型的中断,它的中断标志已经为"1",尽管AVR没有马上响应,但标志位保持着,等代AVR的响应(称为中断挂起).当AVR从中断返回后,如果标志位没有被软件清除,在执行一条指令后,会响应该中断的(尽管中断产生条件已经过去了).
对于第二类型的中断(不设置标志位的),在AVR执行中断的过程中肯定不不会响应的.当AVR从中断返回后,如果该中断的产生条件还存在,那么AVR执行一条指令后,响应该中断;如果中断产生条件不成立了,AVR就不会响应了(丢失一次中断). 谢谢!讲得很详细,不过还没看懂,有待慢慢消化 留下 我已经买了书了 谢谢马老师 呵呵 ATmega128 是128KB FLASH 谢谢马老师,讲解得很通俗! 是个老帖子了,看了还是有些收获,但是有一点疑惑,借块宝地和大家能讨论一下:
2.Flash较小的AVR芯片,其一个中断向量占据1个字的空间,用于放置一条相对转移RJMP指令(范围-2K~+2K字),跳到中断服务程序。对于不使用的中断,在中断向量区中应放置1条中断返回指令RETI,增强程序的抗干扰性。
3.ATmega128的Flash空间为64K字,因此它的一个中断向量占据2个字的空间,用于放置一条绝对转移JMP指令(指令长度为2个字),跳到中断服务程序。对于不使用的中断,在中断向量区中应连续放置2条中断返回指令RETI,增强程序的抗干扰性。当使用汇编语言编写系统程序时应注意。
对马老师提出的这两条,说实话,很久以前我是这样用的,并且我也是这样想的。但是今天才仔细去想,大家可以讨论一下是不是真的能起到我们想要的作用,大家的智慧才是最有用的。
先说一下我的观点:这两条的意思是在PC跑飞时并且恰好跑到了未用的中断向量区(其实可以扩展为任意一个中断向量区)时,我们期望让它返回的正常执行的程序位置。
实际上能不能实现呢?首先,如果外设产生中断并且CPU响应中断,硬件会自动保存PC,而程序跑飞时,大家认为是否会保存当前的PC值呢?如果保存,可能性是多大呢?如果保存,会怎么样,如果不保存,会怎么样?
首先,我个人认为,任何作为外设的中断源出错,都不会引起CPU误动作到PC跑飞的情况。也就是跑飞本身是CPU的问题。如果CPU的数据被修改掉,比如打开了某个中断源并同时打开满足该中断源的条件,也认为CPU是正常的,但是既然寄存器都改变了,RAM区的其他数据绝对不会安全,这个时候,无论程序指针是否正常,都无任何的意义,甚至有些时候会导致致命的错误甚至安全问题。
其次,如果不是控制寄存器被改掉,仅程序指针跑飞。我认为硬件不会对PC压栈(CPU设计的是不响应中断就不会压栈,这是仅是程序跑飞,当然不会压栈),既然不会压栈,那就是说如果当前正在执行某个程序,结果跑飞到中断向量区了,那就相当于这个程序提前返回了,如果没有返回值,只是有可能会正常,如果有返回值,肯定不会正常。而如果用操作系统,则更麻烦,消息队列,任务控制块的数据等等都会改变。显然,不会正常。 呵呵。还有,既然程序PC跑飞了,谁会知道他就会飞一次呢?这种情况任何人包括CPU都不会知道会产生什么样的结果。
测试方法(这种是片面性的,但是没有想到更好的方法):一般用汇编比较直观(C会直接跳出中断向量区,不过也可以到汇编环境里去找到中断向量区)
ORG $0010
RETI
定义函数1 ,函数2,主函数
主调用1,一调用2
调用2时,运行1步后,修改PC值到0010
看看RETI返回后会有什么结果
我说到第一种情况没有测试。
本贴被 wqsjob 编辑过,最后修改时间:2008-10-18,20:46:24. 程序跑飞到了没用的中断向量区,系统肯定出问题了。
在cvavr中,没用的中断向量填充的是 jmp 0000,即从头开始重新执行。推荐使用这个补救的方法。
但最好程序不要乱,乱了什么都很难判断,什么都可能发生。任何其它的方法也都是补救,不一定有效的。 马老师:
请教当使用BOOTLOADER更新时,将原来在应用区的中断向量转移到BOOT区后,如果此时有中断产生,那么,程序如何运行?
中断服务子程序是否也应当写入BOOT区?不然,BOOT区程序运行时如何做中断处理?那么当中断子程序被更新时,如何处理? 请教当使用BOOTLOADER更新时,将原来在应用区的中断向量转移到BOOT区后,如果此时有中断产生,那么,程序如何运行?
不管是用户程序还是BOOT程序,响应中断后,首先转到中断向量处,无论中断向量在头部,还是BOOT区。中断向量处应该是一条转移到中断服务的转移指令。这个跟正常中断完全一样。
----------------------------------------------------------------------------------------------------------
中断服务子程序是否也应当写入BOOT区?不然,BOOT区程序运行时如何做中断处理?那么当中断子程序被更新时,如何处理?
1。首先不赞成使用中断向量的迁移,BOOT程序也不要使用中断。这样最简单,剩掉许多麻烦。
2。如果BOOT一定要使用中断,那么中断服务只能在BOOT区。因为用户区要被覆盖掉的。
3。在BOOT区中的内容要更改,通常只能使用其它办法,随BOOT程序一起更新。用BOOT更新BOOT,不是那么容易的。
谢谢,马老师了。看来BOOT中还是查询简单,可靠。 。完整的中断向量见第二章表2-23
请问这个在哪里呢??????????????? lz位的帖子是2004年的,它是当时编写《M128》书中的部分。
你使用那个型号的芯片,可以直接查该芯片的手册,里面都列出的。 不错、不错 请问马老师,bascom avr软件如何使用stk500下载啊,我设置了stk500,也选择了stk500.exe(avr studio文件夹下得),执行编程时跳出一个dos一样的框,一闪就没了 我理解的中断优先级:
如果同时来了多个中断,不论优先级,都会相应位置1中断状态位。再由中断控制器根据优先级,判定优先响应最高优先级的中断,由后台程序转去执行最高优先级中断服务。最高优先级中断服务完成后,会再转去较低优先级中断服务,依此类推。这样,保证了中断的优先级响应顺序,同时也不会丢失中断。
中断一般是不会丢的。除非这样情况,在某个中断服务程序里头,由于中断是暂时屏蔽的,另外第二个中断源产生了多次(>=2次)。程序中断服务程序里返回后,只会执行一次第二个中断源的中断服务,而不会是多次。
请马老师指正。 楼上基本正确。但这是针对大多数普通的可挂起的中断情况。注意AVR还有个别特殊的不能挂起的中断,如外部中断的底电平触发中断。 马老师 凌晨2:44回帖啊~~
不能挂起的中断怎么理解?
是这个意思吧。
针对 外部中断低电平触发,一旦外部中断线保持低电平,可能发生误中断。需要特别注意的是,在中断服务程序里将外部中断线拉高,防止误中断。 挂号又分为“性病”“妇科”“男科”“内科”“外科” ....
不知道楼上的楼上,是指一种?http://www.ourdev.cn/bbs/emotion/em020.gif 38楼:
1)不一定要使用“挂号”,也可以使用“登记”的说法。总会找到一个合适的说法,如过没有更好的名词来表达,不用也不会影响交流。
51流行的年代,印象中也没有这种名词。在我读过的计算机科学的书,没有看到过这种说法。不排除将来会有,因为科学在发展,软件,
硬件技术都在发展。
2)在计算机硬件学科-- 一个与软件学科联系密切的科学使用不同含义 名词“挂起”(一个操作系统传统术语)的名词,引起的是更多的
误解,混乱。
3)“挂起”一词是否合适,相信马老师比我更清楚。
4)虽然我没有机会读 大学,但是网友给予了我很多的帮助,也使我明白到做学问的 人,就应该有做学术的作风。
-------------------------
5)39楼:你可以随便选一个。你的贴对讨论没有帮助。
-------------------------
6)
网上有许多虚假的广告,不能因为多而相信。
网站也有很多写得乱七八糟的键盘程序,也不能因为它多就认为它好。
古典集合论经历了百多年,不是一样倒下去。
我不想做太长的辩论,有不同的看法,我会提出。这是一个喜欢读书,喜欢思考的人--我的性格。 哈哈 to 楼上,是否有点激动。倒是没这个必要吧
我对“挂起”的理解
所谓可“挂起”的中断是指在中断标志里有相应位代表,比如串口接收中断,当收到一个字节后,就会在相应的中断标志位置位,如果此时处理器正在忙别的程序,可以过会再回来发现和执行这个串口接收中断,这样的情况就相当于中断被短暂的挂起了,跟操作系统里任务的挂起有异曲同工之妙,称谓“挂起”非常符合,ls不觉得么?!
而对于更多的外部中断,是没有相应的中断标志位来标识中断发生的,这个时候如果不能立即执行这个中断,则可能漏掉它。这样的中断称谓“不能挂起”的中断,也是同样道理。
我认为,这样定义“中断挂起”非常形象!! 6)
网上有许多虚假的广告,不能因为多而相信。
网站也有很多写得乱七八糟的键盘程序,也不能因为它多就认为它好。
古典集合论经历了百多年,不是一样倒下去。
网上的东西,也没人逼着你下载当现成的用啊!不排除有人不负责任乱涂乱画,但这种交流无疑是利大于弊,大家都很渴望交流学习。
你自己轻信别人,给人吭了就回头来怨恨所有的人,是不是不太合适呢!?
我觉得大家都有自己的判断能力,善意的提醒是好的!!呵呵 多余不多余就看大家怎么看了。。 41楼:
1)我只是认为不应该使用这样的逻辑来辩理。
2)对次贴的其他内容,我拟不再讨论--无穷无尽讨论,我目前无力进行。认为合理者,继续下去。善意的交流探讨会令人收益不浅。
谢谢楼上的回贴。 只可意会,不可言传。马老师辛苦了,呵呵...... 简单回应41楼。
41楼的说法相信是“挂起中断”创始者的认识,我也曾尝试这样理解,但我否定了。
1)首先,马老师在这里是将中断分类,这是应该明确的。
2)我们应当知道,在这里,中断有两个含义,A)中断事件,B)中断服务程序。每一个中断事件都有其相应的中断服务程序。在平常的工程实践中
我们常常不加以区分。
3)在AVR中,任何一个中断服务程序在一定的条件下都可以被另一个中断服务程序中断。见马老师的回贴:
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=753701&bbs_page_no=1&bbs_id=1003这实际上是说,任何一个中断程序都可以被令一个中
断服务程序中断,也就是说任何一个中断服务程序都是可以被挂起的。不存在决对不能挂起的中断服务程序(条件是开中断)。
4)马老师所说的“挂起中断”,描述的实际上是一个被登记了尚为被服务的中断事件。如果说是挂起了一种中断服务程序,那么如3)所述,并不存
在不可挂起的中断服务程序。
5)如此来看,定义挂起中断,不可挂起中断,除了标新立异,有何意义呢? 学习 好文,学习~学习 ddddddddddddd 马老师您好,讲的好!
想加您QQ183163631 ji 学习~学习 GCC要考虑中断现场保护和恢复的处理么? 楼上的,同一个贴都不看就问的?请看第9楼马老师的回复。
【9楼】 machao
积分:5226
派别:
等级:------
来自:
凡是采用高级语言开发平台编写中断服务程序,程序员一般均不必考虑中断现场的保护和恢复处理。由编译器自动生成。
上面讲过,中断嵌套这么处理:
B中断的服务程序应这样设计:(1)B中断的现场保护;(2)屏蔽除A以外其它的中断允许标志;(3)用指令SEI开放允许全局中断;(4)B中断服务;(5)用指令CLI禁止全局中断(6)恢复在本中断程序被屏蔽的中断允许标志;(7)B中断现场恢复;(8)B中断返回。
这么处理后,在第3步之前和第5步之后,中断还是不能嵌套的。
24M晶振,我现在想用定时器中断产生非常精确的定时处理(8u),由于有串口中断,没加上如上的处理时,定时中断有时是9u,10u,最长可能有12u.加上如上的处理后,还是不能非常非常的精确,还会有9u,10u的情况产生。
还能不能更进一步改进? 受教 好,学习了~~~ 虽然用过中断 但是还不知道bootloader 是怎么回事 初学 非常有用的帖子,解开了我的迷惑!不顶都不行呀 回复【10楼】bairg521随风飘逝
-----------------------------------------------------------------------
那么也就是说在执行程序时有可能出现中断嵌套不能实现的功能是吗??马老师 听课,好多人不知道AVR的中断嵌套,接触过,不过也遇到过一些问题,研究中…… 好 了解了。去实践检验一下 非常有用啊 马老师这个太经典了 马老师这个确实很经典 mark.....................
看上去有点难,好好研究一下! 总结一下,AVR中断优先级还是有用的。但是是在某种编译环境下才是有用的。 说的很明确了,如果这个没有错误可以视为一个官方版本。 多谢楼主分享 多谢楼主分享 linhonggui2007 发表于 2012-10-23 23:15 static/image/common/back.gif
总结一下,AVR中断优先级还是有用的。但是是在某种编译环境下才是有用的。 ...
这个跟编译环境没有任何的关系。不要不懂装懂。 machao 发表于 2013-4-16 23:53 static/image/common/back.gif
这个跟编译环境没有任何的关系。不要不懂装懂。
经过实践确实没有关系,如果Timer0在执行中断的时候打开了其他中断sei();那么有其他中断的时候,比例Timer1;Time0会跳出中断去执行另外一个中断。此时,与中断优先级没有关系。 linhonggui2007 发表于 2013-4-18 23:42 static/image/common/back.gif
经过实践确实没有关系,如果Timer0在执行中断的时候打开了其他中断sei();那么有其他中断的时候,比例T ...
这个解释还是非专业和严谨的。应该为:
1、如果Timer0在执行中断服务过程中的时候打开了中断允许(sei);当只有一个其它中断产生(不管其中断优先级比TIME0高还是低)的时候,Time0的中断服务就会中断打断,去执行另外一个中断服务,形成中断嵌套。此时中断优先级不起作用。
2、如果Timer0在执行中断服务过程中的时候打开了中断允许(sei);当同时产生了2个以上的中断请求,那么这两个新产生的中断求中优先级高的一个将打断此时的TIME0的中断服务,形成中断嵌套。对于多个同时(注意!是同时)产生中断的情况,优先级起作用,MCU将实现相应级别最高的那个中断。
页:
[1]