Atmel处理器复位,但MCUSR中没有指示复位源

时间:2011-12-11 17:56:27

标签: c assembly embedded atmel

短篇小说:

那些复位条件是什么,它们不会在ATmega处理器的MCUSR中设置一点,但仍会导致复位?

长篇故事:

我在ATmega168中使用欠压检测,并在我的代码中有一个位置来处理它。如果我的系统断电,电容器会将其保持在褐色水平以上大约半秒钟,当我恢复供电时,掉电处理程序会成功运行。 (我检查MCUSR中的掉电位。)

然而,当我慢慢降低系统电压并慢慢将其恢复时,处理器重新启动,并且掉电处理程序不运行:MCUSR为零! (我通过DebugWire使用外部调试器来检查它。)

这会导致什么?如果它是别的东西,比如监视器被意外启用(我不使用它,并在启动时禁用它),那么MCUSR中至少会有一些东西。

但不,它既不是看门狗复位(第3位),欠压复位(第2位),外部复位(第1位),也不是上电复位(第0位),所以是什么< / strong>确实导致重置,如果以上都没有?

另一个奇怪的事情是:在这种情况下,在某些情况下,复位将定期发生,在MCUSR中始终为零值。

否则,如果没有发生这种情况,系统将始终完美运行。

修改

我无法在其他地方找到确凿的答案,堆栈溢出会发生什么样的重置,或类似的软件相关错误导致?也许这些条件可能会重置处理器,并让MCUSR独自存在?我认为这样的条件只会破坏RAM甚至程序计数器,但不会导致重置。

3 个答案:

答案 0 :(得分:3)

堆栈溢出不会导致重置。堆栈溢出纯粹是一种软件条件,可能会导致未定义的行为。堆栈溢出可能导致许多症状。例如:

  1. 行为没有明显变化
  2. 相邻内存的损坏会导致意外或未定义的行为,例如引用空指针或执行无效指令
  3. 如果处理器执行无效指令并且未处理异常,则堆栈溢出可能出现以导致重置。这又是软件定义的行为,具体取决于软件异常处理程序。取消引用NULL指针或指向无效内存空间的指针也会发生同样的事情。

    您可能需要仔细检查是否没有其他寄存器可以指定重置原因。

    您提到降低电压然后升高电压。如果只是降低电压,它会重置吗?你有监控电压的代码吗?我想知道为什么你怀疑软件条件错误是你改变硬件条件的原因。

答案 1 :(得分:1)

如果它有任何区别,您是否尝试过使用BODLEVEL保险丝?

但是,这可能很容易由堆栈溢出或其他一些软件问题引起。特别是如果你正在使用函数指针 - 它可能只是跳转到0.我过去遇到过这样的问题。

从来没有真的这样做,但我相信如果你检查一下你在软件中更改的其他寄存器的值,你可以轻松区分重置和'跳转'。如果真的是复位寄存器也应该重新初始化。 例如。在代码中的某处将PORTB设置为0x55。然后在启动时检查其值。如果是复位则应为0x00,否则应保持为0x55。

答案 2 :(得分:0)

如果你使用avrgcc试试这个:

volatile char mcusr __attribute__ ((section (".noinit")));
void main(void){
  mcusr=MCUSR;
  ...
  if(mcusr&0x01)printf("WD");
  if(mcusr&0x02)printf("EX");
  if(mcusr&0x04)printf("BO");
  if(mcusr&0x08)printf("PO");
  ...
}