sbx110 发表于 2013-7-7 22:37:47

AVR Atmel studio 6.0 C++ 中断实例,真的很疼

  首先,名字打得很认真,是为了让大家能馊得到。其次,用AVR Studio,真的很蛋疼。

  很疼1:Atmel studio 6.0用软件仿真时,需要关闭防火墙。我还没有找到更好的方法,有高手知道其它方法的话,还望不吝赐教。

  很疼2:大多数资料显示,studio 6中断还是用ISR(向量)。找了很多资料,都没有说具体怎么把中断例程做成类的友元。后来查看了<interrupt.h>,才发现ISR是一个宏,有兴趣的朋友可以打开头文件查看一下。
  好了,废话少说,真接上代码:

  在类的头文件里如此声明:
        extern "C" void TIMER1_CAPT_vect(void);
        class TIMER
        {
        private:
                friend        void        TIMER1_CAPT_vect(void);
                static volatile unsigned char        Time1Out;
        };

  在CPP文件里如此声明和定义中断函数:
        extern "C" void TIMER1_CAPT_vect (void) __attribute__ ((signal,__INTR_ATTRS));
        void TIMER1_CAPT_vect (void)
        {
                TIMER::Time1Out ++;
        }

  为什么中断函数的声明和定义这么怪,我就不多说了,看一下<interrupt.h>就什么都明白了。TIMER1_CAPT_vect不能乱写,在一个头文件里有定义,具体哪个文件忘了。
  另外例子有点简单,也不全,不能直接拿来编译,还望见谅。

  很疼3:这可能是最蛋疼的了。

  变量定义如下:
        volatile unsigned char        Cnt = 0;

  代码一:
        if (! (Cnt & 0x03))        {...}

  代码二:
        Cnt        &=        0x03;
        if (! Cnt)        {...}

  这两段代码都是想判断Cnt低两位是否为0,但是反汇编出来的代码显示,第一段代码比第二段代码多出三条汇编指令。第一段代码把Cnt当字来处理了,即使我用各种强制转换的组合,编译出来的代码始终是字处理。而第二段代码是按字节处理的。
  还有一种情况,当把第一段代码的0x03改为0xf3或0x13,编译结果为字节处理;如果把0x03改为0x07、0x0f等等,编译结果还是字处理。

  一开始以为AVR Studio 4.x如此,后来换了6.0结果一样。真的无语了,就用网友的一句话来形容吧:真的很蛋疼!
  以上代码用的单片机是ATMEGA8,如果我哪里做得不对,还望不吝赐教。

  写完这么多,想起一个笑话:
  甲:代码编译不通过。
  乙:加一个空格。

  最可笑的是,我不知道该如何评判乙说得话。我不知道该说乙是高手还是...

postek 发表于 2014-10-10 16:02:38

1啥防火墙? 我用6.2没这问题。能在防火墙中设置一下不?
2 怎么个怪法?
3 代码2的Cnt 多个赋值操作吧?

Felix257 发表于 2014-10-10 16:06:19

postek 发表于 2014-10-10 16:02
1啥防火墙? 我用6.2没这问题。能在防火墙中设置一下不?
2 怎么个怪法?
3 代码2的Cnt 多个赋值操作吧? ...

13年纪念芦沟桥事变的帖子了……
页: [1]
查看完整版本: AVR Atmel studio 6.0 C++ 中断实例,真的很疼