1.概述
在产品设计中,我们经常会使用到看门狗功能,通过程序中设计的定时时间,周期的进行喂狗操作,从而保证程序运行在正常设计的程序流程,在程序运行有偏差的时候可以及时的纠正,防止异常的发生!
小华HC32F488系列MCU带有两个看门狗计数器,一种是计数时钟源为专用内部 RC(SWDTLRC: 10KHz)的专用看门狗计数器(SWDT),另一种是计数时钟源为 PCLK3 的通用看门狗计数器(WDT)。专用看门狗和通用看门狗是 16 位递减计数器,用来监测由于外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行而产生的软件故障。
2.共同点和不同点
都支持窗口功能:在计数开始前可预设窗口区间,计数值位于窗口区间时,可刷新计数器,计数重新开始。
都支持两种启动方式:硬件启动方式和软件启动方式。
都支持两种中断复位产生条件:一种是计数器计数产生下溢;一种是在刷新允许区间之外执行刷新动作, 产生刷新错误。
专用看门狗计数器(SWDT)的时钟源是固定10KHz的LRC,通用看门狗计数器(WDT)的时钟源是PCLK3。
3.例程
3.1.专用看门狗计数器(SWDT)
设置软件启动SWDT,并以约0.62秒进行一次喂狗操作,正常启动情况下LED_BLUE闪烁;按下按键K5则触发错误区间刷新动作,导致SWDT触发复位动作,SWDT触发复位后LED_RED常亮。
#define EXAMPLE_PERIPH_WE (LL_PERIPH_GPIO | LL_PERIPH_EFM | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU)
#define EXAMPLE_PERIPH_WP (LL_PERIPH_EFM | LL_PERIPH_FCG)
#define SWDT_COUNT_PERIOD (256U)
static void SWDT_Config(void)
{
stc_swdt_init_t stcSwdtInit;
/* SWDT configuration */
stcSwdtInit.u32CountPeriod = SWDT_CNT_PERIOD256;
stcSwdtInit.u32ClockDiv = SWDT_CLK_DIV32;
stcSwdtInit.u32RefreshRange = SWDT_RANGE_0TO25PCT;
stcSwdtInit.u32LPMCount = SWDT_LPM_CNT_STOP;
stcSwdtInit.u32ExceptionType = SWDT_EXP_TYPE_RST;
(void)SWDT_Init(&stcSwdtInit);
}
int32_t main(void)
{
uint16_t u16CmpVal;
uint32_t u32ResetSrc = 0UL;
/* Peripheral registers write unprotected */
LL_PERIPH_WE(EXAMPLE_PERIPH_WE);
/* Configure BSP */
BSP_IO_Init();
BSP_LED_Init();
BSP_KEY_Init();
/* Get RMU information */
if (SET == RMU_GetStatus(RMU_FLAG_SWDT)) {
u32ResetSrc = RMU_FLAG_SWDT;
BSP_LED_On(LED_RED);
}
RMU_ClearStatus();
/* Configure SWDT */
SWDT_Config();
/* First reload counter to start SWDT */
SWDT_FeedDog();
/* Wait for SWDT module to complete initial */
DDL_DelayMS(10U);
/* Count period=256, range=0%-25% */
u16CmpVal = SWDT_COUNT_PERIOD / 4U;
/* Peripheral registers write protected */
LL_PERIPH_WP(EXAMPLE_PERIPH_WP);
for (;;) {
if (SET == BSP_KEY_GetStatus(BSP_KEY_5)) {
u16CmpVal = SWDT_COUNT_PERIOD / 2U;
}
if (SWDT_GetCountValue() < u16CmpVal) {
SWDT_FeedDog();
/* Wait for the count value to update */
DDL_DelayMS(10U);
if (0UL == u32ResetSrc) {
BSP_LED_Toggle(LED_BLUE);
}
}
}
}
3.2.通用看门狗计数器(WDT)
设置软件启动WDT,并设置约1.05秒触发一次WDT计数溢出中断,通过按键K5循环切换工作模式(正常模式、睡眠模式),正常模式LED_BLUE闪烁,睡眠模式LED_RED闪烁。
#define EXAMPLE_PERIPH_WE (LL_PERIPH_GPIO | LL_PERIPH_EFM | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU)
#define EXAMPLE_PERIPH_WP (LL_PERIPH_EFM | LL_PERIPH_FCG)
#define WDT_INT_SRC (INT_SRC_WDT_REFUDF)
#define WDT_IRQ_NUM (INT006_IRQn)
static __IO uint8_t u8ExtIntCount = 0U;
static void WDT_IrqCallback(void)
{
en_flag_status_t enFlagSta;
DDL_DelayUS(30);
enFlagSta = WDT_GetStatus(WDT_FLAG_UDF);
/* WDT underflow interrupt */
if (SET == enFlagSta) {
(void)WDT_ClearStatus(WDT_FLAG_UDF);
/* Normal mode */
if (0U == u8ExtIntCount) {
BSP_LED_Toggle(LED_BLUE);
} else {
/* Sleep mode */
BSP_LED_Toggle(LED_RED);
}
}
WDT_FeedDog();
}
void BSP_KEY_KEY5_IrqCallback(void)
{
u8ExtIntCount++;
if (u8ExtIntCount >= 2U) {
u8ExtIntCount = 0U;
}
BSP_LED_Off(LED_RED);
BSP_LED_Off(LED_BLUE);
}
static void WDT_Config(void)
{
stc_wdt_init_t stcWdtInit;
stc_irq_signin_config_t stcIrqSignConfig;
/* WDT configuration */
stcWdtInit.u32CountPeriod = WDT_CNT_PERIOD16384;
stcWdtInit.u32ClockDiv = WDT_CLK_DIV512;
stcWdtInit.u32RefreshRange = WDT_RANGE_0TO100PCT;
stcWdtInit.u32LPMCount = WDT_LPM_CNT_CONT;
stcWdtInit.u32ExceptionType = WDT_EXP_TYPE_INT;
(void)WDT_Init(&stcWdtInit);
/* Interrupt configuration */
stcIrqSignConfig.enIntSrc = WDT_INT_SRC;
stcIrqSignConfig.enIRQn = WDT_IRQ_NUM;
stcIrqSignConfig.pfnCallback = &WDT_IrqCallback;
(void)INTC_IrqSignIn(&stcIrqSignConfig);
NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);
}
int32_t main(void)
{
/* Peripheral registers write unprotected */
LL_PERIPH_WE(EXAMPLE_PERIPH_WE);
/* Configure BSP */
BSP_IO_Init();
BSP_LED_Init();
BSP_KEY_Init();
/* Configure WDT */
WDT_Config();
/* First reload counter to start WDT */
WDT_FeedDog();
/* Peripheral registers write protected */
LL_PERIPH_WP(EXAMPLE_PERIPH_WP);
for (;;) {
/* Sleep mode */
if (1U == u8ExtIntCount) {
PWC_SLEEP_Enter(PWC_SLEEP_WFI);
} else {
/* Reserved */
}
}
}
4.运行结果
4.1.专用看门狗计数器(SWDT)
按下复位按键复位芯片,LED_BLUE闪烁;按下按键K5触发错误刷新动作;看门狗复位,LED_RED常亮。
1
4.2.通用看门狗计数器(WDT)
按下复位按键复位芯片,进入正常模式LED_BLUE闪烁;按下按键K5切换工作状态到睡眠模式,LED_RED闪烁;再次按下按键K5切换工作状态到正常模式,LED_BLUE闪烁。
2