"); //-->
单片机程序死机,跑飞了可以从以下几个方面查找原因:
1. 意外中断。是否打开了某个中断,但是没有响应和清除中端标志,导致程序一直进入中断,造成死机假象
2. 中断变量处理不妥。若定义某些会在中断中修改的全局变量,这时要注意两个问题:首先为了防止编译器优化中断变量,要在这些变量定义时前加volatile,其次在主循环中读取中断变量前应该首先关闭全局中断,防止读到一半被中断给修改了,读完之后再打开全局中断;否则出现造成数据乱套。
3. 地址溢出,常见错误为指针操作错误。我要着重说的是数组下标使用循环函数中循环变量,如果循环变量没控制好则会出现数组下标越界,意外修改系统的寄存器造成死机,这种情况下如果死机说明运气好,否则后面不知道发生什么头疼的事。
4. 无条件的死循环;比如使用while(x);等待电平变化,正常情况下x都会变成0,就怕万一,因此最好加上时间限制;
5. 看门狗没有关闭。有的单片机即使没使用看门狗开机时也有可能意外自动开启了最小周期的看门狗,导致软件不断复位,造成死机,这个要看芯片手册,最好在程序复位后首先应该显式清除看门狗再关闭看门狗;
6. 堆栈溢出。最难查找的问题,对于容量小的单片机,尽量减少函数调用层级,减少局部变量,从而减少压栈的时候所需的空间。当你把以上几条都试过不能解决问题,试一试把你的被调用少函数直接内置到调用的地方并且把占用RAM大的局部变量改成全局变量,试一试说不定就可以了。
1.中断或主函数中有死循环,现象是程序停在某处。
2.堆栈溢出。现象是程序跑飞。
**************************************************************************************************
3、是否开了中断但是没有用。如:
开了中断:
TA0CCTL0 = CCIE; // CCR0 interrupt enabled
TA0CCTL1 = CCIE; // CCR1 interrupt enabled//时间周期1使能
TA0CCTL2 = CCIE; // CCR2 interrupt enabled//时间周期2使能
TA0CCTL3= CCIE; // CCR3 interrupt enabled//时间周期3使能
但是:
定时器中:
case 4: ( TA0CCTL2 = CCIE; )和 case 6: ( TA0CCTL3= CCIE; )内没有处理的程序。
……
case 2:
TA0CCR1 +=1024; // Add Offset to CCR2
SecondReach=1;
CountToMunite++;
Rquestinterval++;
SecondTimecount++;
break; // CCR4 not used
case 4:
break;
case 6:
break;
case 8:
break; // CCR3 not used
……
4、数组越界。定义的数组只有50个单元,但是程序运行的过程中,却给他赋给50+个单元。
解决办法:
A.看中断有没有用 _EINT(),引起中断嵌套.
B.Project--Options--General Options---Stack/Heap 将Stack size设置大一些。 (堆栈溢出)
3.中断耗时太长,刚出中断又进去了.这时的现象是程序一直在中断中执行,回不到主函数。 (中断嵌套)
4.检查CPU的电源是不是稳定,msp430在要保证程序正常运行,需保证Vcc大于1.8V。当电压低至0.8V时,程序仍有可能执行。这时的现象是PC指针乱飞,有复位,死机,停在中断,时钟频率发生变化等现象。
5.程序编译没问题,下载程序后上电不断复位,该问题是由于WDT造成的(RAM的初始化时间大于WDT默认的32MS时间,因此MSP复位)根本原因是初始化的时间过长,超过了看门狗的时间,初始化完成以后才能进入main函数,这时关狗已经来不及了。
解决的办法:
A 对你的数组用 __no init_定义,上电编译器不产生特殊的附加函数去初始化RAM.
B 在Project--Options--Linker--Config中选择 Override default programe,并将Entry lib 设置成 __program_start这时要修改Cstartup.S43(记得把它加入复制到工程而不是修改系统的),在第一条指令前加入关狗的指令,在main函数里再开(如果需要的话)。
如果用汇编,则没有这个问题
6、把无用的中断允许关掉。
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。