繁体   English   中英

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

[英]Atmel processor is reset, but there is no reset source indicated in MCUSR

小故事:

哪些复位条件不会在 ATmega 处理器的MCUSR中设置位,但仍会导致复位?

长长的故事:

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

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

什么会导致这种情况? 如果是其他原因,例如意外启用了看门狗(我不使用它,并在启动时禁用它),那么MCUSR中至少会有一些东西。

但是,没有,这既不是看门狗复位(第3位),掉电复位(第2位),外部复位(第1位),或上电复位(位0),所以有什么做的原因复位,如果没有的以上??

另一件奇怪的事情:在这种情况之后,在某些情况下,复位会周期性地发生,MCUSR 中的值总是为零。

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

编辑:

我在其他地方找不到决定性的答案,堆栈溢出或类似的与软件相关的错误会导致什么样的重置? 也许这些条件可能会重置处理器,而不管 MCUSR? 我认为这种情况只会损坏 RAM 甚至程序计数器,但不会导致重置。

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

  1. 行为无明显变化
  2. 相邻内存的损坏会导致意外或未定义的行为,例如推迟空指针或执行无效指令

如果处理器执行无效指令并且未处理异常,则堆栈溢出可能导致复位。 这又是取决于软件异常处理程序的软件定义行为。 取消引用NULL指针或指向无效内存空间的指针也会发生同样的事情。

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

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

如果有任何不同,您是否尝试过使用 BODLEVEL 保险丝?

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

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

如果你使用 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");
  ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM