MSP430G2553编程用到看门狗,TI官方例程没有看门狗喂狗例程,上网搜了看门狗例程,有两个地方给出的看门狗初始化代码是WDTCTL = WDT_ARST_1000(1秒的看门狗),喂狗程序是WDTCTL=WDT_ARST_1000+WDTCNTCL。经过测试,初始化代码没有问题,不喂狗的情况下每隔1秒重启一次。但这个喂狗程序是有问题的,用这个喂狗程序看门狗会停掉,也就是看门狗回失去作用。表面上程序没有重启,好像喂狗程序起作用了,但实际是看门狗停掉了。(只把喂狗程序放到初始化最后面运行一次就知道了)
仔细看代码发现WDT_ARST_1000的定义是这样的:#define WDT_ARST_1000 (WDTPW+WDTCNTCL+WDTSSEL) ,也就是WDT_ARST_1000已经加了个WDTCNTCL(0x0008),再加一个相当于加了0x0010,也就是将WDTTMSEL置位了,从看门狗模式变成了计时中断模式,导致看门狗不起作用了。
接下来试了其他几种喂狗程序,官方的手册给出的喂狗程序如下:
Periodically clear an active watchdog
MOV #WDTPW+WDTCNTCL,&WDTCTL
虽然是汇编,但意思应该是WDTPW+WDTCNTCL的值赋给寄存器WDTCTL,所以用了以下喂狗程序:
WDTCTL = WDTPW+WDTCNTCL;
貌似是OK的,但仔细看下发现有问题,因为直接给WDTCTL这样赋值相当于WDTCTL=WDT_MRST_32WDT_MRST_32,因为
/* WDT is clocked by fSMCLK (assumed 1MHz) */
#define WDT_MRST_32 (WDTPW+WDTCNTCL) /* 32ms interval (default) */
也就是这样喂狗可以是可以但同时把看门狗时间改成了32ms,因为直接赋值改变了其它位,所以很容易想到采用|=操作:
WDTCTL |= WDTPW+WDTCNTCL;
看上去很合理,但发现这个喂狗程序根本不起作用,过一秒就重启。仔细看了下手册原因可能是这样的,WDTPW是看门狗密码,读的时候是0x69,写的时候必须写成0x5A。WDTCTL |= WDTPW+WDTCNTCL等价于
WDTCTL = WDTCTL+WDTPW+WDTCNTCL
也就是读出来密码0x69或上要写的密码WDTPW(0x5A),密码就不对了,所以操作该寄存器不成功喂狗失败。
试了以上各种方法,发现喂狗程序其实很简单,跟初始化程序一样即可:
WDTCTL = WDT_ARST_1000;
到最后发现初始化和喂狗程序都很简单,但是这里面有跟多个隐蔽的坑,稍不注意就掉进去了,并且看门狗一般是程序的最后一道保障,想想都可怕