[AVR单片机] 【 【 关于MEGA8 的 死机 探讨 】 】

[复制链接]
 楼主| sparkstar 发表于 2007-4-4 14:01 | 显示全部楼层 |阅读模式
     我公司是家电控制板配套厂商,MCU需求量颇大!以前采用freescale的多!目前对于MEGA8 芯片比较感兴趣!但在测试过程中发现一些问题,在这里提出来供各位同仁参考!也欢迎双龙公司的专家指点!

     这里主要想说一下死机的问题!先说一个最简单的实验把,采用的是ATMGA8L—8PU芯片,用四个IO口(PB4、PB5、PC0、PC4)从板子上引长线(2米多)到显示板,显示板上就是四个发光二极管(串电阻,共阳极接法),软件编程用到了SIG_OVERFLOW0 定时中断,控制IO口一1Hz频率亮灭发光二极管。再对显示延长线作EMC测试时发现频繁复位,欧尔出现死机现象(即去处干扰后系统仍然不能恢复,发光管常亮不灭,上电或手动复位可恢复)

     主要容丝位配置如下:采用内部4M RC振荡,BOD=2.7V,WDT常开

     在这里暂时不讨论如何优化硬件,单说说死机现象(这个太严重了!),我的程序也非常的简单,里面没有任何的死循环,也没有可能任何数据表,就是定时置IO口,控制LED。喂狗的方式采用中断置标志位,在主程序中喂狗的方法。

     此时的死机是不是指已经不是单纯的PC指针跑飞,而是整个系统都紊乱了,包括WDT。

     希望专家们能从死机的本质上面谈一谈!


     我以前用的单片机功能上确实没有MEGA8强大,报价也要高一点,但同样的测试也会复位(复位频率明显比MEGA8低),却未发现过死机现象!

     
ayb_ice 发表于 2007-4-4 14:30 | 显示全部楼层

事实胜于雄辩

事实胜于雄辩...
dai_weis 发表于 2007-4-5 08:12 | 显示全部楼层

几个不清楚的问题

不是专家不知道可不可以探讨?
一、复位引脚怎么做的处理
二、IO引线过长,不知道其他的MCU是不是也这样用?一般要用驱动电路
三、如果电压不是3.3VBOD最好设在4.0V上
四、请问是如何知道的PC指针跑飞,而是整个系统都紊乱了,包括WDT
用的什么办法?
 楼主| sparkstar 发表于 2007-4-5 08:23 | 显示全部楼层

关于 :

关于 :

一、复位引脚怎么做的处理
二、IO引线过长,不知道其他的MCU是不是也这样用?一般要用驱动电路
三、如果电压不是3.3VBOD最好设在4.0V上 


优化硬件当然一定程度上可以缓解死机现象,这里我想探讨一下MEAG8死机的实质是什么?是看门狗打没了?还是系统紊乱了?怎么紊乱了? 


四、请问是如何知道的PC指针跑飞,而是整个系统都紊乱了,包括WDT
我这个实验软件很简单,就是加大干扰会死机! 会复位我可以理解,但死机就不好解释了 
dai_weis 发表于 2007-4-5 08:29 | 显示全部楼层

看来没法弄明白了

不知道楼上知不知道合理的硬件才是可靠工作的基础,没有基础有什么可讨论的,做产品又不是做论文,那我告诉你为什么,你的MCU可能工作的不合理的硬件基础上,所以挂了。
 楼主| sparkstar 发表于 2007-4-5 09:05 | 显示全部楼层

关于楼上的观点我不敢苟同!

关于楼上的观点我不敢苟同!

优化硬件当然一定程度上可以缓解死机现象,这里我想探讨一下MEAG8死机的实质是什么?似乎不像单纯的PC跑飞,而且硬件并没有损坏,可以手动复位。
 楼主| sparkstar 发表于 2007-4-5 09:32 | 显示全部楼层

再次公布最新实验结果:

再次公布最新实验结果: 

发现LED全亮,但亮度有所下降,去处干扰后,用示波器测量IO口,发现IO口仍然输出方波,但频率由1Hz增加到1KHz。 


这是中断程序,每次都配置了相关寄存器,不会出现持续寄存器错误的。 难道是内部振荡频率打变了? 

SIGNAL(SIG_OVERFLOW0) 

   TCCR0 = 0x03; 
   TIMSK=_BV(TOIE0); 
   TCNT0=256-(CPU_CLOCK_HZ/TICKS_PER_SEC/64); 
    
    bSysTimEn; 
 楼主| sparkstar 发表于 2007-4-5 09:52 | 显示全部楼层



//间隔1ms
void SysTimerModule(void)
{

    static INT16U  Sec = 0;
    static INT8U   bOn = 0;
    
    
    if (bSysTimIsDis)
        return;
    
    bSysTimDis;
    
    wdt_reset();
    wdt_enable(WDTO_2S);

    
    if ( ++Sec > 1000/(1000/TICKS_PER_SEC)  )
    {
        Sec = 0;

        BitSet(DDRB,PB4);
        BitSet(DDRB,PB5);
        BitSet(DDRC,PC0);
        BitSet(DDRC,PC4);
        if (bOn)
        {
            bOn = 0;
            BitSet(PORTB,PB4);
            BitSet(PORTB,PB5);
            BitSet(PORTC,PC0);
            BitSet(PORTC,PC4);
        }
        else
        {
            bOn = 1;
            BitClr(PORTB,PB4);
            BitClr(PORTB,PB5);
            BitClr(PORTC,PC0);
            BitClr(PORTC,PC4);
        }


    }
}

以上为系统计时程序在主程序中循环调用它。


内部时钟频率变化加快1000倍是没可能的! 而且是正好1000倍。我的定时程序又是1ms次,似乎像是。。。
MicroMMU 发表于 2007-4-5 11:49 | 显示全部楼层

加大MCU电源电容试下先。

可能是电源受到干扰后不稳定造成的。
ayb_ice 发表于 2007-4-5 14:24 | 显示全部楼层

随便说说

AVR本身就不那么好...
 楼主| sparkstar 发表于 2007-4-5 14:40 | 显示全部楼层

mega8的功能还是很不错的,

mega8的功能还是很不错的,批量价格也有优势,关键是性能方面,因为我这边的量还是比较大的,出口单比较多,不敢大意
 
NE5532 发表于 2007-4-5 19:35 | 显示全部楼层

死机包括硬件的“死锁”

MicroMMU 发表于 2007-4-5 23:19 | 显示全部楼层

死机的本质

要不是CPU死锁,就是外围死锁。
死锁通常会发热。到烧溃。
不知是否发热。

另外长线一定是要隔离的。像你那样做的话基本上没有一款MCU能不复位的。
我们用MCU的原则是采取措施后能稳定就OK了。换句话说你那样做是EMC设计就有问题。想又好又便的事可能比较难。
xwj 发表于 2007-4-5 23:33 | 显示全部楼层

我觉得:死机的本质,就是某个地方的电荷在干扰下移位了

可能是某个门或MOS管非正常导通,从而产生大电流、可控硅效应;
也可能是某个寄存器或RAM或ExROM的值变了,造成PC值改变、RAM改变、程序代码改变等等等等。。。


后者并不一定就单纯的改变PC指针的,比如改变的是PLL的分频寄存器,当然就会出LZ所说的现象哦
 楼主| sparkstar 发表于 2007-4-6 08:54 | 显示全部楼层

公布:最近测试现象

先将简化的源代码贴出来 
这里简化一下程序再贴出来: 

//间隔1ms  
void SysTimerModule(void)  
{  
    static INT16U  Sec = 0;  
   static INT8U   bOn = 0;  
   static INT8U   BeepCount = 0;  
      
   if (bSysTimIsDis)  
        return;  
   
    bSysTimDis;  
     
   wdt_reset();  
    wdt_enable(WDTO_2S);  
     
   if ( ++Sec > 1000/(1000/TICKS_PER_SEC)  )  
   {  
       Sec = 0;  

      BitSet(DDRB,PB4);  
      BitSet(DDRB,PB5);  
      BitSet(DDRC,PC0);  
      BitSet(DDRC,PC4);  
      if (bOn)  
      {  
          bOn = 0;  
         BitSet(PORTB,PB4);  
          BitSet(PORTB,PB5);  
          BitSet(PORTC,PC0);  
          BitSet(PORTC,PC4);  
      }  
      else  
      {  
          bOn = 1;  
         BitClr(PORTB,PB4);  
          BitClr(PORTB,PB5);  
          BitClr(PORTC,PC0);  
          BitClr(PORTC,PC4);  
      }  

        BeepCount++;          
      if ( BeepCount < 5 )  
      {  
          BeepOn;     
      }  
      else  
      {  
          BeepOff;  
          BeepCount = 5;  
      }  
    }  
}  

SIGNAL(SIG_OVERFLOW0)  
{  
   TCCR0 = 0x03;  
   TIMSK=_BV(TOIE0);  
   TCNT0=256-(CPU_CLOCK_HZ/TICKS_PER_SEC/64);  
     
    bSysTimEn;  
}  

INT16S main (void)  
{  
    wdt_enable(WDTO_2S);  
     
   TCCR0 = 0x03;  
   TIMSK=_BV(TOIE0);  
   TCNT0=256-(CPU_CLOCK_HZ/TICKS_PER_SEC/64);  

   sei ();  

   for (;;)   
   {  
       SysTimerModule();  
    }  

    return (0);  
}  



刚做了一下实验,在主程序中将 
 if ( ++Sec > 1000/(1000/TICKS_PER_SEC)  )   
改为 
 if ( ++Sec > 500/(1000/TICKS_PER_SEC)  ) 

即在主程序中将IO口输出频率增加到2Hz,打干扰后仍然出现死机现象,而且和以前一样,IO口输出1kHz的方波 


然后修改中断定时时间,将将IO口输出频率增加到2Hz,在打干扰试一下看看   ,修改中断定时间隔为0.5ms后,打干扰后仍然出现死机现象,而且和以前不一一样,IO口输出2kHz的方波; 



这样看来似乎程序仍在运行,看门狗也正常,但“死机”后单片机竟然有选择地直接跳过了if ( ++Sec > 1000/(1000/TICKS_PER_SEC)  )  语句, 导致IO口输出频率增加。 有点匪夷所思了!!!! 
 楼主| sparkstar 发表于 2007-4-6 10:19 | 显示全部楼层

继续公布:

   “死机”死的这么智能! 竟然会直接跳过比较语句? 是不可能的,初步怀疑干扰造成了内部RAM控制、读、写单元失效,导致每次Sec都大于(1000/(1000/TICKS_PER_SEC)),所以IO口输出频率提高! 

    增加一下代码以作测试: 

    volatile INT16U Tmp16; 

    。。。。 
    
    Tmp16 = Sec; 
    ++Sec; 
    ++Tmp16; 

    if ( Tmp16 != Sec ) 
   for(;;); 

    if ( Sec > 1000/(1000/TICKS_PER_SEC)  ) 
    { 
       。。。。 



    发现复位频率明显提高!MCU几乎在不停的复位中。长时间干扰仍然有死机现象。死机现象和以前不同,发现IO口常高、常低现象。似乎是看门狗也没了,单片机进入的死循环一般。芯片没有明显发热现象,不象可控硅效应。 
 楼主| sparkstar 发表于 2007-4-6 10:21 | 显示全部楼层

另外来个题外话:

21ic的AVR板块这是怎么了? 好像人气有大大的下降啊! 我也算21ic的老客了。希望斑竹,双龙多点点火啊!
ayb_ice 发表于 2007-4-6 10:23 | 显示全部楼层

死机的本质

死机的本质应该是PC跑飞了,程序进入无限循环吧...
不过上面的情况更可怕哟...
sf101mabo 发表于 2007-4-6 10:36 | 显示全部楼层

软件问题

内部寄存器紊乱或程序跑飞,更有可能的是软件有问题。
除非硬件出现故障,否则硬件死锁的可能性很小。
加光电隔离吧
 楼主| sparkstar 发表于 2007-4-6 14:39 | 显示全部楼层

暂时的结论:

暂时的结论: 
     MEGA8的IO口经受强干扰的情况下,易导致内部的RAM读、写、控制单元失效,且此失效在干扰除去后无法自愈,但可以通过WDT复位恢复! 

程序作如下修改后未发现死机现象 

         。。。。
         volatile static INT16U  Sec = 0;
         。。。。。 
   if ( ++Sec > 1000/(1000/TICKS_PER_SEC)  ) 
   { 
       Sec = 0; 
       
             if ( Sec != 0 ) 
          for(;;); 
    
       。。。。 


建议;各位使用MEGA8单片机的朋友,最好加上RAM功能效验程序。 
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

20

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部