通过对上面寄存器描述分析,可以得出以下结论:
/通过设置WTCON[5]来设置看门狗定时器的使能
/在开启看门狗定时器后,通过设置WTCON[15:8]和[4:3]位来设置看门狗控制器的工作时钟频率,具体看门狗的递减时间间隔可以通过下面的公式算出:
t_watchdog = 1/( PCLK / (Prescaler value + 1) / Division_factor )
注: t_watchdog:看门狗控制器递减时间间隔(单位秒)
PCLK:APB总线工作时钟(单位Hz)
Prescaler value: 8位分频器预设值
Division_factor:除数因子
/通过设置WTCON[2] 和WTCON[0]位,来使能产生中断和复位信号
/通过设置WTDAT来设置计数值
3、看门狗实验
MINI2440在没有初始化系统时钟时,整个开发板由一个12MHz的外部晶振提供频率,PCLK工作频率也是12MHz,WTCON[15:8]设置为74,除数因子选择16,通过上面公式可以计算出,看门狗控制器递减时间间隔0.1毫秒。将WTCNT里的值设置为0x2710(十进制10000),那么看门狗会每过一秒钟产生一次超时。
- ; 关闭看门狗实验
- ldr r0, = 0x53000000 ; WTCON寄存器地址加载到r0
- mov r1, #0 ; r1 = 0
- str r1, [r0] ; 将r1里的值存到r0里地址里
复制代码
通过分析前面的寄存器的设置位可知,只要设置WTCON[5]为0即可,上述代码里,直接将整个WTCON寄存器里的位设置为0。
开启看门狗实验:
- WTCON EQU 0x53000000 ; 看门狗控制寄存器
- WTCNT EQU 0x53000008 ; 看门狗计数寄存器
-
- AREA WATCHDOG_ENABLE,CODE,READONLY
- ENTRY
- ; 设置看门狗控制寄存器
- ldr r0, =WTCON ; 加载WTCON寄存器地址
- ; 0x4a21 = [15:8]=74, [5]=1, [0]=1
- ldr r1, =0x4a21 ; 将0x4a21保存到r1里
- str r1, [r0] ; 将r1里的值存入r0指向的地址
- ; 设置看门狗计数寄存器,该寄存器的值在上电后被加载, 1秒超时
- ldr r2, = WTCNT ; 加载WTCNT寄存器地址
- ldr r3, =0x2710 ; 将0x2710保存到r1里
- str r3, [r2] ; 将r3里的值存入r2指向的地址
-
- IMPORT led_on ; 引入led_on符号
- bl led_on ; 调用led_on代码
-
- loop
- B loop ; 死循环
- END
复制代码
程序开始定义两个常量地址,分别是WTCON,WTCNT的地址,ENRTY后面是程序的正文部分,首先通过ldr指令加载WTCON的地址到r0里,将0x4a21这个数加载到r1里,0x4a21是我们通过设置WTCON [15:8]=74 [7:6]=0,[5]=1,[4:1]=0, [0]=1得到的16进制数,将其值存入到r0地址里,这样WTCON里就是我们设置各位的值,然后同样道理再将0x2710存到WTCNT数据寄存器里,设置数据寄存器的值为0x2710。
为了看到看门狗的重启效果,我们加入了一个小程序,用来点亮led灯,将上述代码在ADS下编译完后,通过H-JTAG烧写到NORFLASH里可以看到每过1秒钟,开发板的led灯就闪一下。
知识扩展
开启了看门狗之后,控制器会定时的复位,为了防止不停的复位,就要进行“喂狗”操作,喂狗操作相对比较简单,只要在WTCNT里的计数减为0之前,将其值重置一个非0的数值即可,看下面的函数:feed_dog(该代码仅供读者参考,光盘源码中没有给出具体例子)
- ; 喂狗程序
- feed_dog
- ldr r0, =WTCNT
- ldr r1, =0x2710
- str r1, [r0]
- mov pc, lr
复制代码
喂狗程序对喂狗的时机必须要合适,否则在定时器还没来得及发生中断调用watchdog已经超时了,也将引起系统复位重启,通常系统里会开启另外一个时钟来为整个系统服务,它会定时的“告知”系统,在看门狗定时器超时之前,自动的调用喂狗程序。