使用背景
为了防止程序跑飞,MCU特意引入了看门狗,看门狗分为窗口看门狗和独立看门狗,窗口看门狗采用中断实现,其时间更加的精确,独立看门狗大约会在附近1S左右没有喂狗就产生看门狗复位。
具体代码实现
#include "bsp_wdt.h"
#include "hc32_ddl.h"
//复位类型
#define RST_POWER_ON 1
#define RST_EXTERNAL 2
#define RST_BROWN_OUT 4
#define RST_WATCHDOG 8
#define RST_JTAG 16
#define RST_SOFTWARE 32
#define RST_BACKUP 64
typedef enum {
RST_CAU_POWER_ON = 0x01,
RST_CAU_EXTERNAL = 0x02,
RST_CAU_BROWN_OUT = 0x04,
RST_CAU_WATCHDOG = 0x08,
RST_CAU_JTAG = 0x10,
RST_CAU_SOFTWARE = 0x20,
RST_CAU_BACKUP = 0x40,
} rst_cause_t;
// pclk = system_clock/div4 = 50M
// max cycle = 65536
// max feed interval = 65536 / (50000000/8192) = 10.7s
void bsp_wdt_init(void)
{
stc_wdt_init_t stcWdtInit;
/* configure structure initialization */
MEM_ZERO_STRUCT(stcWdtInit);
stcWdtInit.enClkDiv = WdtPclk3Div8192;
stcWdtInit.enCountCycle = WdtCountCycle65536;
stcWdtInit.enRefreshRange = WdtRefresh100Pct;
stcWdtInit.enSleepModeCountEn = Disable;
stcWdtInit.enRequestType = WdtTriggerResetRequest;
WDT_Init(&stcWdtInit);
}
void bsp_wdt_refresh(void)
{
en_result_t enRet = Error;
enRet = WDT_RefreshCounter();
if(enRet != Ok) {
printf("Failed at function: %s, line: %d\n", __FUNCTION__, __LINE__);
}
}
//获取复位类型
uint8_t rmu_get_reset_flag(void)
{
uint8_t res;
stc_rmu_rstcause_t stcRmuRstCause;
MEM_ZERO_STRUCT(stcRmuRstCause);
RMU_GetResetCause(&stcRmuRstCause);
if(Set == stcRmuRstCause.enSoftware) {
res = RST_CAU_SOFTWARE;
} else if(Set == stcRmuRstCause.enWdt) {
res = RST_CAU_WATCHDOG;
} else if(Set == stcRmuRstCause.enRstPin) {
res = RST_CAU_EXTERNAL;
}
return res;
}
//清除复位标志
void rmu_clear_reset_flag(void)
{
RMU_ClrResetFlag();
}
int main()
{
while(1)
{
const byte mcuFlag = rmu_get_reset_flag();
if (mcuFlag & RST_POWER_ON)
printf("RST_POWER_ON");
if (mcuFlag & RST_EXTERNAL)
printf("RST_POWER_ON");
if (mcuFlag & RST_BROWN_OUT)
printf("RST_POWER_ON");
if (mcuFlag & RST_WATCHDOG)
printf("RST_POWER_ON");
if (mcuFlag & RST_SOFTWARE)
printf("RST_POWER_ON");
rmu_clear_reset_flag();
}
}