×
单片机 > 单片机程序设计 > 详情

lpc1114看门狗_窗口看门狗

发布时间:2020-06-08 发布时间:
|

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

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

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

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

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

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

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

WDWINDOW:看门狗窗口寄存器

符号描述复位值
23:0WINDOW看门狗窗口值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行,设置喂狗最大值,窗口值。





『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
C51 特殊功能寄存器SFR的名称和地址