WWDG窗口看门狗

发布于 2023-01-24  213 次阅读


WWDG简介

Window watchdog,即窗口看门狗,能产生系统复位信号和提前唤醒中断的计数器。

特性

1.当递减计数器值从 0x40减到0x3F时复位(即T6位跳变到0)
2.计数器的值大于W[6:0]值时喂狗会复位
3.提前唤醒中断 (EWI):当递减计数器等于 0x40 时可产生

喂狗

在窗口期内重装载计数器的值,防止复位

用途

用于监测单片机程序运行时效是否精准,主要检测软件异常,需要精准检测程序运行时间的场合

工作原理

WWDG寄存器

控制寄存器

(WWDG_CR) 用于使能窗口看门狗工作,以及重装载计数器值(即喂狗)

配置寄存器

(WWDG_CFR)用于使能窗口看门狗提前唤醒中断,设置预分频系数,设置窗口上限值

状态寄存器

(WWDG_SR)用于判断是否发生了WWDG提前唤醒中断

超时时间计算

WWDG最短最长超时时间(F1系列)

配置步骤

1.工作参数初始化

HAL_WWDG_Init()

/**
* @brief 初始化窗口看门狗
* @param tr: T[6:0],计数器值
* @param tw: W[6:0],窗口值
* @note fprer:分频系数(WDGTB) ,范围:WWDG_PRESCALER_1~WWDG_PRESCALER_8,表示
2^WDGTB 分频。 Fwwdg=PCLK1/(4096*2^fprer). 一般 PCLK1=36Mhz
最大-最小超时时间参考 RM0008 或者《STM32F10xxx 参考手册》 P321
* @retval 无
*/
void wwdg_init(uint8_t tr, uint8_t wr, uint32_t fprer)
{
wwdg_handler.Instance = WWDG;
wwdg_handler.Init.Prescaler = fprer; /* 设置分频系数 */
wwdg_handler.Init.Window = wr; /* 设置窗口值 */
wwdg_handler.Init.Counter = tr; /* 设置计数器值 */
wwdg_handler.Init.EWIMode = WWDG_EWI_ENABLE; /* 使能窗口看门狗提前唤醒中断 */
HAL_WWDG_Init(&wwdg_handler); /* 初始化 WWDG */
}

Msp初始化

/**
* @brief WWDG MSP 回调
* @param WWDG 句柄
* @note 此函数会被 HAL_WWDG_Init()调用
* @retval 无
*/
void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg)
{
__HAL_RCC_WWDG1_CLK_ENABLE(); /* 使能窗口看门狗时钟 */
HAL_NVIC_SetPriority(WWDG_IRQn,2,3); /* 抢占优先级 2,子优先级为 3 */
HAL_NVIC_EnableIRQ(WWDG_IRQn); /* 使能窗口看门狗中断 */
}

3.编写中断服务函数

void WWDG_IRQHandler(void)
{
    HAL_WWDG_IRQHandler(&g_wwdg_handle);
}

4.重定义提前唤醒回调函数

/**
* @brief 窗口看门狗喂狗提醒中断服务回调函数
* @param wwdg 句柄
* @note 此函数会被 HAL_WWDG_IRQHandler()调用
* @retval 无
*/
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef* hwwdg)
{
HAL_WWDG_Refresh(&g_wwdg_handle); /* 更新窗口看门狗值 */
LED1_TOGGLE(); /* LED1 闪烁 */
}

main.c 代码

int main(void)
{
HAL_Init(); /* 初始化 HAL 库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
usart_init(115200); /* 串口初始化为 115200 */
led_init(); /* 初始化 LED */
LED0(0); /* 点亮 LED0 红灯 */
delay_ms(300); /* 延时 300ms 再初始化看门狗,LED0 的变化"可见" */
wwdg_init(0X7F, 0X5F, WWDG_PRESCALER_8); /* 计数值为 7f,窗口值为 5f,分频数为 8 */
while (1)
{
LED0(1); /* 关闭红灯 */
}
}

调用 wwdg_init(0X7F,0X5F,WWDG_PRESCALER_8)这个语句,就设置计数器值为 7f, 窗口
寄存器为 5f, 分频数为 8,然后可由前面的公式得到 Twwdg=4096× 8× 64/36MHz=58.25ms,即
超时时间就是 58.25ms。 58.25ms 进中断喂狗一次,并翻转 LED1。

  • alipay_img
  • wechat_img
想法不去做终究就只是想法
最后更新于 2023-01-24