登录 免费注册 首页 | 行业黑名单 | 帮助
维库电子市场网
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统
驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe

请问在ATMANAVR中,进中断后是自动保护现场吗?

作者:liu_xw217 栏目:单片机
请问在ATMANAVR中,进中断后是自动保护现场吗?

        我还用加CLI()和SEI()吗!

多谢谢

2楼: >>参与讨论
sailz
我的看法
默认方式是关闭了中断, 就是说中断无法被打断.
自动保护现场,恩.



3楼: >>参与讨论
testcode
应该吧
GCCAVR中,中断后是自动保护现场

4楼: >>参与讨论
勇敢的心
atmanavr的编译器就是gcc
注意gcc中的SIGNAL和INTERRUPT的区别

5楼: >>参与讨论
zlei
SIGNAL和INTERRUPT的区别
SIGNAL和INTERRUPT的自动保护现场应该没有区别吧!是否自动保护现场和关键字"naked"有关

SIGNAL:
Introduces an interrupt handler function that runs with GLOBAL interrupts  initially disabled.

INTERRUPT:
    Introduces an interrupt handler function that runs with GLOBAL interrupts initially enabled. This allows interrupt handlers to be interrupted.  

中断函数都会自动保护现场的,两者主要区别就是在ISR中,INTERRUPT多了一条sei语句,这样就允许ISR被其他中断所中断。

下面是测试程序
//! Interrupt handler for tcnt0 overflow interrupt
SIGNAL(SIG_OVERFLOW0)
{
    Timer0Reg0++;            // increment low-order counter

    // increment pause counter
    TimerPauseReg++;

    // if a user function is defined, execute it too
    if(TimerIntFunc[TIMER0OVERFLOW_INT])
        TimerIntFunc[TIMER0OVERFLOW_INT]();
}
汇编代码如下:

633                   .LFE20:
635                   .GLOBAL    __vector_9
637                   __vector_9:
638                   .LFB21:
639                   .LM70:
640                   /* prologue: frame size=0 */

641 02b0 1F92              PUSH __zero_reg__
642 02b2 0F92              PUSH __tmp_reg__
643 02b4 0FB6              in __tmp_reg__,__SREG__
644 02b6 0F92              PUSH __tmp_reg__
645 02b8 1124              clr __zero_reg__
646 02BA 2F93              PUSH r18
647 02bc 3F93              PUSH r19
648 02be 4F93              PUSH r20
649 02c0 5F93              PUSH r21
650 02c2 6F93              PUSH r22
651 02c4 7F93              PUSH r23
652 02c6 8F93              PUSH r24
653 02c8 9F93              PUSH r25
654 02ca AF93              PUSH r26
655 02cc BF93              PUSH r27
656 02ce EF93              PUSH r30
657 02d0 FF93              PUSH r31
658                   /* prologue end (size=17) */
659                   .LM71:
660 02d2 8091 0000         lds r24,Timer0Reg0
661 02d6 9091 0000         lds r25,(Timer0Reg0)+1
662 02da A091 0000         lds r26,(Timer0Reg0)+2
663 02de B091 0000         lds r27,(Timer0Reg0)+3
664 02e2 0196              adiw r24,1
665 02e4 A11D              adc r26,__zero_reg__
666 02e6 B11D              adc r27,__zero_reg__
667 02e8 8093 0000         sts Timer0Reg0,r24
668 02ec 9093 0000         sts (Timer0Reg0)+1,r25
669 02f0 A093 0000         sts (Timer0Reg0)+2,r26
670 02f4 B093 0000         sts (Timer0Reg0)+3,r27
671                   .LM72:
672 02f8 8091 0000         lds r24,TimerPauseReg
673 02fc 9091 0000         lds r25,(TimerPauseReg)+1
674 0300 A091 0000         lds r26,(TimerPauseReg)+2
675 0304 B091 0000         lds r27,(TimerPauseReg)+3
676 0308 0196              adiw r24,1
677 030A A11D              adc r26,__zero_reg__
678 030c B11D              adc r27,__zero_reg__
679 030e 8093 0000         sts TimerPauseReg,r24
680 0312 9093 0000         sts (TimerPauseReg)+1,r25
681 0316 A093 0000         sts (TimerPauseReg)+2,r26
682 031a B093 0000         sts (TimerPauseReg)+3,r27
683                   .LM73:
684 031e 8091 0000         lds r24,TimerIntFunc
685 0322 9091 0000         lds r25,(TimerIntFunc)+1
686 0326 892B              or r24,r25
687 0328 29F0              breq .L44
688                   .LM74:
689 032A E091 0000         lds r30,TimerIntFunc
690 032e F091 0000         lds r31,(TimerIntFunc)+1
691 0332 0995              icall
692                   .L44:
693                   /* epilogue: frame size=0 */
694 0334 FF91              pop
6楼: >>参与讨论
zlei
如果不想保护现场,看看EMPTY_INTERRUPT就知道如何实现了
#ifdef __cplusplus
#define EMPTY_INTERRUPT(signame)                \
extern "C" void signame(void);                  \
void signame (void) __attribute__ ((naked));    \
void signame (void) {  __asm__ __volatile__ ("reti" ::); }
#else
#define EMPTY_INTERRUPT(signame)                \
void signame (void) __attribute__ ((naked));    \
void signame (void) { __asm__ __volatile__ ("reti" ::); }
#endif


同样的测试代码

7楼: >>参与讨论
hotpower
当然也可不保护就是危险些
 
8楼: >>参与讨论
sailz
我又学到东西了
INTERRUPT和SIGNAL的区别.
在atmanavr的帮助文件里有简略介绍.

参与讨论
昵称:
讨论内容:
 
 
相关帖子
我的 m48 居然不启动了
请问RS422通信芯片接线怎样接
请教:中断号的问题
WinAvr编译的代码长度
单片机的功能
免费注册为维库电子开发网会员,参与电子工程师社区讨论,点此进入


Copyright © 1998-2006 www.dzsc.com 浙ICP证030469号