短篇小说:
那些复位条件是什么,它们不会在ATmega处理器的MCUSR
中设置一点,但仍会导致复位?
长篇故事:
我在ATmega168中使用欠压检测,并在我的代码中有一个位置来处理它。如果我的系统断电,电容器会将其保持在褐色水平以上大约半秒钟,当我恢复供电时,掉电处理程序会成功运行。 (我检查MCUSR
中的掉电位。)
然而,当我慢慢降低系统电压并慢慢将其恢复时,处理器重新启动,并且掉电处理程序不运行:MCUSR
为零! (我通过DebugWire使用外部调试器来检查它。)
这会导致什么?如果它是别的东西,比如监视器被意外启用(我不使用它,并在启动时禁用它),那么MCUSR
中至少会有一些东西。
但不,它既不是看门狗复位(第3位),欠压复位(第2位),外部复位(第1位),也不是上电复位(第0位),所以是什么< / strong>确实导致重置,如果以上都没有?
另一个奇怪的事情是:在这种情况下,在某些情况下,复位将定期发生,在MCUSR中始终为零值。
否则,如果没有发生这种情况,系统将始终完美运行。
修改
我无法在其他地方找到确凿的答案,堆栈溢出会发生什么样的重置,或类似的软件相关错误导致?也许这些条件可能会重置处理器,并让MCUSR独自存在?我认为这样的条件只会破坏RAM甚至程序计数器,但不会导致重置。
答案 0 :(得分: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");
...
}