本帖最后由 guiyan 于 2024-9-20 18:18 编辑
前言
本篇节重点介绍G32A1445芯片的看门狗的应用和测试。
一、基本功能介绍
1.1 时钟源- BUS_CLOCK(总线时钟)
- LPO(低功耗振荡器)
- SYSOSC(系统振荡器时钟)
- LSICLK(低速内部时钟)
看门狗的时钟源一般选择128 KHz LPO 作为时钟源。
1.2 喂狗
由特定的时序才能完成,0xB480A602写入到CNT寄存器中,或者0xA602,0xB480分2次写入。
1.3 解锁
通过解锁,可以再次配置更新相关的寄存器位域。
用户必须在 16 个总线时钟内输入完整的解锁序列,并在 128 个总线时钟内完成重新配置,否则解锁窗口将被关闭,需要重新输入解锁序列。
由特定的时序才能完成, 0xD928C520写入到CNT寄存器中,或者0xC520,0xD928分2次写入。
1.4 窗口模式
如果使能窗口模式并设置窗口值,那么当计数器值在窗口值范围内没有被刷新,则会产生复位。
刷新机制如下图所示:
1.5 溢出复位
看门狗的计数器CNT如果发生溢出,可以立即引起复位,也可以启用中断服务函数,延时128 bus clocks才引起系统复位;
也可以再延长(通过配置RMU外设,514 LPO cycles )。
系统复位的延迟时间具体情况,如下表所示:
WDT_CSTS
[WDTIEN]
| RMU_RSTIEN
[WDTEIN]
| RMU_RSTIEN
[GIEN]
| 中断
| 延迟与复位
| 0
| 0
| 0
| -
| 看门狗复位
| 0
| 0
| 1
| -
| 看门狗复位
| 0
| 1
| 0
| -
| 无中断, RMU 延迟看门狗复位
| 0
| 1
| 1
| RMU IRQ
| RMU 中断, RMU 延迟看门狗复位
| 1
| 0
| 0
| WDT IRQ
| 看门狗中断,看门狗延迟看门狗复位
| 1
| 0
| 1
| WDT IRQ
| 看门狗中断,看门狗延迟看门狗复位
| 1
| 1
| 0
| WDT IRQ
| 看门狗中断,看门狗延迟+RMU 延迟看门狗复位
| 1
| 1
| 1
| WDT IRQ(RMU IRQ 被挂起)
| 看门狗中断,看门狗延迟+RMU 延迟看门狗复位
|
二、实验测试
本实验是测试系统复位的延时时间。本实验的BUS_CLOCK(总线时钟)是48MHz。
总体思路:
首先配置好看门狗,开启窗口模式,使能WDT中断。
在WDT中断函数中,添加GPIO翻转的代码,观察GPIO翻转波形的时长,即可测试出看门狗计数器溢出,到系统复位的总时长。
然后利用滴答时钟中断函数,进行喂狗。判断按键KEY1按下,则失能滴答时钟中断,停止喂狗,等待触发WDT中断。
2.1 看门狗的配置const WDT_CONFIG_T wdtConfig =
{
.clkSrc = WDT_LPO_CLOCK, //时钟源为128KHz LPO
.updateEnable = true,
.intEnable = true, //使能WDT中断,延长系统复位时间
.timeoutValue = 64000U,
.windowEnable = true, //开启窗口模式
.windowValue = 30000U,
.prescalerEnable = false, //不分频
.opMode =
{
false, /* Wait Mode */
false, /* Stop Mode */
false /* Debug Mode*/
}
};
2.2 利用滴答时钟中断进行喂狗void SysTick_Handler(void)
{
if (WDT_ReadCounter(WDT_INSTANCE) > wdtConfig.windowValue) //判断计数器值在窗口内,就进行喂狗
{
/* Reset Watchdog counter */
INT_SYS_DisableIRQGlobal();
WDT_HW_Refresh(WDT); //特定的时序,进行喂狗
INT_SYS_EnableIRQGlobal();
printf("Feed WDT \r\n");
}
}
2.3 WDT中断函数void WDT_EWDT_IRQHandler(void)
{
if(WDT->CSTS.reg & 0x4000) //Watchdog Interrupt Flag
{
while(1)
{
GPIOD->PLLOT.reg = (1U << 16U);//翻转PD16,观察波形的输出时间,即可测试出系统复位延时时间
}
}
}
2.4 main函数主体逻辑if(POWER_SYS_ReadResetSrcStatus(RMU, RMU_BY_WATCH_DOG) == true)//判断复位源是不是看门狗引起的系统复位
{
printf("******************************** \r\n");
printf("Reset by WDT, disable WDT now \r\n");
WDT_DeInit(WDT_INSTANCE);
LED_On(LED_RED);
}
else
{
SysTick_Init();
status = WDT_Init(WDT_INSTANCE, &wdtConfig);
if(status == STATUS_SUCCESS)
{
LED_On(LED_GREEN);
}
}
while(1)
{
/* Put down KEY1, disable the systick */
if (BTN_GetState(BUTTON_KEY1) == 0)
{
G32_SysTick->CSR.reg = 0U; //停止喂狗
}
}
2.5 测试情况
本实验的BUS_CLOCK(总线时钟)是48MHz,128个BUS_CLOCK 就约等于2.6us。
实测符合预期。
2.6 使能RMU中断,再次延长系统复位时间
RMU中断函数
void RMU_IRQHandler(void)
{
if(WDT->CSTS.reg & 0x4000) //Watchdog Interrupt Flag
{
while(1)
{
GPIOD->PLLOT.reg = (1U << 16U);
}
}
}
main函数主体逻辑代码
if(POWER_SYS_ReadResetSrcStatus(RMU, RMU_BY_WATCH_DOG) == true)
{
printf("******************************** \r\n");
printf("Reset by WDT, disable WDT now \r\n");
WDT_DeInit(WDT_INSTANCE);
LED_On(LED_RED);
}
else
{
SysTick_Init();
status = WDT_Init(WDT_INSTANCE, &wdtConfig);
if(status == STATUS_SUCCESS)
{
LED_On(LED_GREEN);
}
INT_SYS_DisableIRQ(WDT_EWDT_IRQn); //失能WDT中断
RMU->RSTIEN.reg = 0x00A3; //配置系统复位延长时间,514 LPO cycles(≈4ms,128kHz)
INT_SYS_EnableIRQ(RMU_IRQn); //使能RMU中断
}
while(1)
{
/* Put down KEY1, disable the systick */
if (BTN_GetState(BUTTON_KEY1) == 0)
{
G32_SysTick->CSR.reg = 0U;
}
}
测试情况:
系统复位延时时间:514 LPO cycles约等于4ms。
实测符合预期。
|
学习学习,感谢大佬分享