lpc1114看门狗_窗口看门狗

  • 学习3621次

看门狗定时器是一个倒计时定时器。假设我们规定,当定时器计数到4000和0之间时喂狗,符合条件。当在大于4000的时候喂狗,和计数器倒数到0没有喂狗都不符合要求。这就是窗口看门狗。在实际应用中,当发生提前喂狗,和没有喂狗都会使得单片机复位,从而使程序得到了双重保护。

如果我们要知道定时器是否计数到了规定的两值之间,最直接的办法当然是读取定时器的当前值,但是这样必须在程序中时刻读取定时器的当前值,不仅给程序带来了很大的负担,而且有些时候,程序无法满足读取当前值的条件。所以,LPC1114中,给出了这么一个寄存器:WDWARNINT。即看门狗提醒中断寄存器。改寄存器的定义如下所示:

WDWARNINT:看门狗提醒中断寄存器

符号 描述 复位值
9:0 WARNINT 看门狗提醒中断比较值 0
31:10 保留位。不能给这些位写1

该寄存器可以设置一个值,当看门狗定时器倒计时到这个值时,产生看门狗中断。该值是个10位的值,最大0x3FF,即1023。

假设窗口看门狗的定时器值范围是4000~0,给WDWARNINT寄存器写入值1023,当定时器倒计时到1023的时候,产生中断,在看门狗中断服务函数里面,写入喂狗的函数,即可解决上面提出的时刻读取计数值的问题。

窗口看门狗的上限值在WDWINDOW寄存器里面定义。

WDWINDOW:看门狗窗口寄存器

符号 描述 复位值
23:0 WINDOW 看门狗窗口值 0xFFFFFF
31:24 保留位,不能给这些位写1

下面做一个示例:

让单片机间隔一定时间给电脑串口发送一个递增的数据。正常情况下,会一直发送。

当我们故意把看门狗定时器中断服务函数里面的喂狗函数去掉,即当定时器倒计时到0时,会产生复位,在电脑串口调试助手上看到的结果将是,当单片机复位,会使得串口调试助手上的数从0开始递增。

当我们故意把看门狗定时器中断服务函数里面的喂狗函数放到发送第一个字节以后,即提前喂狗,将会使得单片机复位,在串口调试助手上,将会一直收到00,即来不及递增,单片机就复位从新开始执行了。

新建一个工程,结果如下图所示:

新建看门狗例程

uart.c文件的介绍,请看第四章内容。

在main.c文件中,输入以下代码:

  1. #include “lpc11xx.h”
  2. #include “wdt.h”
  3. #include “uart.h”
  1. void delay(void)
  2. {
  3. ???uint16_t i,j;
  1. ???for(i=0;i<5000;i++)
  2. ??????for(j=0;j<280;j++);
  3. }
  1. void WDT_IRQHandler(void)
  2. {
  3. ???LPC_WDT->MOD &= ~(0x1<<2);
  4. ???WDTFeed();
  5. }
  1. int main()
  2. {
  3. ???uint8_t cnt=0;
  1. ???UART_init(9600);
  2. ???WDT_Window_Enable();
  3. ???NVIC_EnableIRQ(WDT_IRQn);
  1. ???while(1)
  2. ???{
  3. ??????UART_send_byte(cnt++);
  4. ??????delay();
  5. ???}
  6. }

从main函数开始看起。

第17行,定义了一个变量,该变量用来递增。

第18行,初始化串口波特率为9600。(关于此函数的详细说明,请看第四章内容。)

第19行,开启窗口看门狗功能。

第20行,开启看门狗中断。

第21~25行,间隔给串口发送递增的数据,循环发送。

在wdt.h中,输入以下代码:

  1. #ifndef __NXPLPC11XX_WDT_H__
  2. #define __NXPLPC11XX_WDT_H__
  1. extern void WDT_Window_Enable(void);
  2. extern void WDTFeed(void);
  3. extern void WDT_IRQHandler(void);
  1. #endif

在wdt.c中,输入以下代码:

#include “lpc11xx.h”

#include “wdt.h”

#include “uart.h”

  1. void WDT_Window_Enable()
  2. {
  3. ???LPC_SYSCON->PDRUNCFG &= ~(0x1<<6); // 看门狗振荡器时钟上电(bit6)
  4. ???LPC_SYSCON->WDTOSCCTRL = (0x1<<5);// WDT_OSC_CLK=300KHz
  5. ???LPC_SYSCON->WDTCLKSEL = 0x2;??????? // 选择看门狗时钟源
  6. ???LPC_SYSCON->WDTCLKUEN = 0x01;????????? // 更新时钟源
  7. ???LPC_SYSCON->WDTCLKUEN = 0x00;????????? // 先写0,再写1达到更新目的
  8. ???LPC_SYSCON->WDTCLKUEN = 0x01;
  9. ???while ( !(LPC_SYSCON->WDTCLKUEN & 0x01) );? // 等待更新成功
  10. ???LPC_SYSCON->WDTCLKDIV = 3;???? // 设置看门狗分频值为3
  11. ???LPC_SYSCON->SYSAHBCLKCTRL |= (1<<15);// 允许WDT时钟
  12. ???LPC_WDT->TC = 25000;??? // 给看门狗定时器赋值,定时时间大约1秒(wdt_clk=100KHz时)
  13. ???LPC_WDT->WARNINT = 1023; // 当看门狗定时器倒数到1023时,产生中断
  14. ???LPC_WDT->WINDOW = 4600; // 最大喂狗值
  15. ???LPC_WDT->MOD |= 0x03;??????? // 写值0x03:不喂狗产生复位
  16. ???LPC_WDT->FEED = 0xAA;??????? // 喂看门狗,开启
  17. ???LPC_WDT->FEED = 0x55;
  18. }
  1. void WDTFeed(void)
  2. {
  3. ???LPC_WDT->FEED = 0xAA;
  4. ???LPC_WDT->FEED = 0x55;
  5. }

和前面的使能看门狗函数相比,只多了第13、14行的代码。

第13行,设置提醒中断值。

第14行,设置喂狗最大值,窗口值。

发表评论