1

短篇小说:

那些不会设置MCUSRATmega 处理器的位但仍会导致复位的复位条件是什么?

长篇大论:

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

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

什么会导致这种情况?如果是其他东西,比如意外启用了看门狗(我不使用它,并在启动时禁用它),那么MCUSR.

但是不,它既不是看门狗复位(第 3 位)、掉电复位(第 2 位)、外部复位(第 1 位),也不是上电复位(第 0 位),那么如果两者都不是,是什么导致了复位以上??

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

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

编辑:

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

4

3 回答 3

3

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

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

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

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

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

于 2011-12-12T00:53:12.473 回答
2

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

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

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

于 2011-12-11T22:22:31.057 回答
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");
  ...
}
于 2012-12-22T12:58:55.697 回答