简短的故事:

那些复位条件是什么,它们不会在ATmega处理器的MCUSR中置位,但仍会引起复位?

长话说:

我在ATmega168中使用了掉电检测,并在代码中占有一席之地。 如果我的系统断电,则电容器会使其保持在电源不足水平之上约半秒钟,并且当我恢复电源时,电源不足处理例程将成功运行。 (我检查了MCUSR中的MCUSR 。)

但是,当我缓慢降低系统电压并缓慢地将其释放时,处理器将重新启动,并且掉电处理例程无法运行: MCUSR为零! (我通过DebugWire使用外部调试器进行检查。)

是什么原因造成的? 如果还有其他情况,例如看门狗被意外启用(我不使用它,而在启动时将其禁用),则MCUSR中至少会有一些东西。

但是不,它既不是看门狗复位(位3),掉电复位(位2),外部复位(位1)或上电复位(位0),那么导致复位的原因是什么都没有以上??

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

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

编辑:

我在其他地方找不到结论性的答案,那么堆栈溢出或类似的软件相关错误会导致哪种复位? 也许这些情况可能会使处理器复位,而使MCUSR独处? 我以为这样的情况只会破坏RAM甚至是程序计数器,但不会引起复位。

===============>>#1 票数:3 已采纳

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

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

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

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

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

===============>>#2 票数:1

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

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

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

===============>>#3 票数: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");
  ...
}

  ask by vsz translate from so

未解决问题?本站智能推荐: