KEA的看门狗是一个独立的特殊定时器。当启动看门狗后,如果你不定时去喂狗,它就认为程序跑飞了,将会复位MCU。
特点
时钟源可选:
bus clockInternal 32 kHz RC oscillatorInternal 1 kHz RC oscillatorExternal clock source Programmable timeout period
Programmable 16-bit timeout valueOptional fixed 256 clock prescaler when longer timeout periods are needed Robust write sequence for counter refresh
Refresh sequence of writing 0x02A6 and then 0x80B4 within 16 bus clocks Window mode option for the refresh mechanism
Programmable 16-bit window valueProvides robust check that program flow is faster than expectedEarly refresh attempts trigger a reset. Optional timeout interrupt to allow post-processing diagnostics
Interrupt request to CPU with interrupt vector for an interrupt service routine (ISR)Forced reset occurs 128 bus clocks after the interrupt vector fetch. Configuration bits are write-once-after-reset to ensure watchdog configuration cannotbe mistakenly altered.Robust write sequence for unlocking write-once configuration bits
Unlock sequence of writing 0x20C5 and then 0x28D9 within 16 bus clocks forallowing updates to write-once configuration bitsSoftware must make updates within 128 bus clocks after unlocking and beforeWDOG closing unlock window.
例程
看门狗设置为:Internal 1 kHz RC oscillator, timeout 1s
main.c
#include "derivative.h"
#include "wdog.h"
void Clk_Init(void);
void Delay(void);
int main(void)
{
Clk_Init();
LED_Init();
WDOG_ConfigType WDOGConfig
= {{0}};
WDOGConfig
.sBits
.bIntEnable
= TRUE
;
WDOGConfig
.sBits
.bWaitEnable
= TRUE
;
WDOGConfig
.sBits
.bStopEnable
= TRUE
;
WDOGConfig
.sBits
.bDbgEnable
= TRUE
;
WDOGConfig
.sBits
.bUpdateEnable
= FALSE
;
WDOGConfig
.sBits
.bDisable
= FALSE
;
WDOGConfig
.sBits
.bClkSrc
= WDOG_CLK_INTERNAL_1KHZ
;
WDOGConfig
.u16TimeOut
= 1000;
WDOGConfig
.u16WinTime
= 0;
WDOG_Init(&WDOGConfig
);
if(WDOG_IsReset())
{
while(1)
{
WDOG_Feed();
LED_Toggle();
Delay();
}
}
for(;;)
{
}
return 0;
}
/***********************************************************************************************
*
* @brief CLK_Init
- Initialize Core Clock to
40MHz
, Bus Clock to
20MHz
* @param none
* @
return none
*
************************************************************************************************/
void Clk_Init(void)
{
ICS_C1
|= ICS_C1_IRCLKEN_MASK
;
ICS_C3
= 0x50;
while(!(ICS_S
& ICS_S_LOCK_MASK
));
ICS_C2
|= ICS_C2_BDIV(1) ;
ICS_S
|= ICS_S_LOCK_MASK
;
}
void Delay(void)
{
uint32_t i
,j
;
for(i
=0 ; i
<8 ; i
++)
for(j
=0 ; j
<65535 ; j
++);
}
wdog.h
#ifndef __WDOG_H__
#define __WDOG_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "derivative.h"
#define WDOG_CLK_BUS 0
#define WDOG_CLK_INTERNAL_32KHZ 2
#define WDOG_CLK_INTERNAL_1KHZ 1
#define WDOG_CLK_EXTERNAL 3
#define WDOG_CLK (WDOG_CLK_INTERNAL_1KHZ)
#define WDOG_Unlock() WDOG->CNT = 0x20C5; WDOG->CNT = 0x28D9
typedef struct {
struct {
uint16_t bIntEnable
: 1;
uint16_t bDisable
: 1;
uint16_t bWaitEnable
: 1;
uint16_t bStopEnable
: 1;
uint16_t bDbgEnable
: 1;
uint16_t bWinEnable
: 1;
uint16_t bUpdateEnable
: 1;
uint16_t bClkSrc
: 2;
uint16_t bPrescaler
: 1;
}sBits
;
uint16_t u16TimeOut
;
uint16_t u16WinTime
;
} WDOG_ConfigType
, *WDOG_ConfigPtr
;
static inline uint8_t
WDOG_IsReset(void)
{ uint32_t u32Status
;
u32Status
= SIM
->SRSID
& SIM_SRSID_WDOG_MASK
;
if(u32Status
)
{
return (1);
}
return (0);
}
void WDOG_Init(WDOG_ConfigPtr pConfig
);
void WDOG_Feed(void);
uint8_t
WDOG_IsReset(void);
#ifdef __cplusplus
}
#endif
#endif
wdog.c
#include "wdog.h"
#include "derivative.h"
#define DisableInterrupts asm(" CPSID i");
#define EnableInterrupts asm(" CPSIE i");
void WDOG_Init(WDOG_ConfigPtr pConfig
)
{
uint8_t u8Cs1
;
uint8_t u8Cs2
;
uint16_t u16Toval
;
uint16_t u16Win
;
u8Cs1
= 0x80;
u8Cs2
= 0;
u16Toval
= pConfig
->u16TimeOut
;
u16Win
= pConfig
->u16WinTime
;
if(pConfig
->sBits
.bDisable
)
{
u8Cs1
&= ~WDOG_CS1_EN_MASK
;
}
else
{
u8Cs1
|= WDOG_CS1_EN_MASK
;
}
if(pConfig
->sBits
.bIntEnable
)
{
u8Cs1
|= WDOG_CS1_INT_MASK
;
Enable_Interrupt(WDOG_EWM_IRQn
);
}
else
{
u8Cs1
&= ~WDOG_CS1_INT_MASK
;
Disable_Interrupt(WDOG_EWM_IRQn
);
}
if(pConfig
->sBits
.bStopEnable
)
{
u8Cs1
|= WDOG_CS1_STOP_MASK
;
}
else
{
u8Cs1
&= ~WDOG_CS1_STOP_MASK
;
}
if(pConfig
->sBits
.bDbgEnable
)
{
u8Cs1
|= WDOG_CS1_DBG_MASK
;
}
else
{
u8Cs1
&= ~WDOG_CS1_DBG_MASK
;
}
if(pConfig
->sBits
.bWaitEnable
)
{
u8Cs1
|= WDOG_CS1_WAIT_MASK
;
}
else
{
u8Cs1
&= ~WDOG_CS1_WAIT_MASK
;
}
if(pConfig
->sBits
.bUpdateEnable
)
{
u8Cs1
|= WDOG_CS1_UPDATE_MASK
;
}
else
{
u8Cs1
&= ~WDOG_CS1_UPDATE_MASK
;
}
if(pConfig
->sBits
.bWinEnable
)
{
u8Cs2
|= WDOG_CS2_WIN_MASK
;
}
else
{
u8Cs2
&= ~WDOG_CS2_WIN_MASK
;
}
if(pConfig
->sBits
.bPrescaler
)
{
u8Cs2
|= WDOG_CS2_PRES_MASK
;
}
u8Cs2
|= (pConfig
->sBits
.bClkSrc
& 0x03);
WDOG_Unlock();
WDOG
->CS2
= u8Cs2
;
WDOG
->TOVAL8B
.TOVALL
= u16Toval
;
WDOG
->TOVAL8B
.TOVALH
= u16Toval
>> 8;
WDOG
->WIN8B
.WINL
= u16Win
;
WDOG
->WIN8B
.WINH
= u16Win
>> 8;
WDOG
->CS1
= u8Cs1
;
}
void WDOG_Feed(void)
{
DisableInterrupts
;
WDOG
->CNT
= 0x02A6;
WDOG
->CNT
= 0x80B4;
EnableInterrupts
;
}