本帖最后由 Afanx 于 2022-10-31 14:12 编辑
窗口看门狗(WWDG)
时钟源:APB1时钟/4096
功能:7位递减计数器,具有上下限(0x7F~0x40),当计数器小于0x40时产生复位,另外只能在计数器小于设定的窗口值才能对计数器重装载。
计数时间:PCLK1=36MHz
预分配 | 计数频率(Hz) | 步进时间(ms) | 最大计数时间(ms) | 2^0 = 1 | 8.789k | 0.113 | 7.28 | 2^1 = 2 | 4.394k | 0.227 | 14.56 | 2^2 = 4 | 2.197k | 0.445 | 29.12 | 2^3 = 8 | 1.098k | 0.910 | 58.25 |
软件配置流程:
1. 配置 RCC_APB1PCLKEN.WWDGEN[11]位使能 WWDG 模块的时钟
2. 软件设置 WWDG_CFG.TIMERB[8:7]位来配置 WWDG 的预分频因子
3. 软件配置 WWDG_CTRL.T[6:0]位,设置计数器的起始值。需要将 WWDG_CTRL.T[6]位设置为 1,以防止在启用后立即复位
4. 配置 WWDG_CFG.W[6:0]位配置上边界窗口值
5. 设置 WWDG_CTRL.ACTB[7]位使能 WWDG
6. 软件操作 WWDG_STS.EWINTF[0]位清除唤醒中断标志
7. 配置 WWDG_CFG.EWINT[9]位使能提前唤醒中断
配置代码:
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] WWDG初始化
*/
void WWDG_Initial(void)
{
/* Enable WWDG clock */
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_WWDG, ENABLE);
/* WWDG clock counter = (PCLK1(36MHz)/4096)/8 = 1099 Hz (~910 us) */
WWDG_SetPrescalerDiv(WWDG_PRESCALER_DIV8);
/* Set Window value to 80; WWDG counter should be refreshed only when the counter
is below 80 (and greater than 64) otherwise a reset will be generated */
WWDG_SetWValue(80);
/* Enable WWDG and set counter value to 127, WWDG timeout = ~910 us * 64 = 58.25 ms
In this case the refresh window is: ~910 us * (127-80) = 42.77 ms < refresh window < ~910 us * 64 = 58.25ms */
WWDG_Enable(127);
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] WWDG测试
*/
void WWDG_Task(void)
{
/* Check if the system has resumed from WWDG reset */
if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET) {
/* WWDGRST flag set */
printf("\r\n reset by WWDG \r\n");
/* Clear reset flags */
RCC_ClrFlag();
}
/* Enable WWDG and set counter value to 127, WWDG timeout = ~910 us * 64 = 58.25 ms
In this case the refresh window is: ~910 us * (127-80) = 42.77 ms < refresh window < ~910 us * 64 = 58.25ms */
while (1) {
/* Delay */
DelayMs(50);
/* Update WWDG counter */
WWDG_SetCnt(127);
/* Toggle LED */
GPIO_ToggleBit(GPIOA, GPIO_PIN_8);
}
}
|