5.18 IWDG 使用说明

本章说明 N32H49x 标准外设库中 IWDG 驱动的文件组成与 7 个公开函数,以及 IWDG_Reset 示例。IWDG 由 LSI 驱动、独立于主程序运行,在死循环或 MCU 卡死时以系统复位恢复;键值、预分频与重装载寄存器的访问保护和配置流程请配合用户手册的“独立看门狗(IWDG)”章节阅读。

5.18.1 相关文件

相对路径 作用
firmware/n32h49x_std_periph_driver/inc/n32h49x_iwdg.h 定义键值、写访问配置、预分频与状态标志枚举,声明 7 个公开函数
firmware/n32h49x_std_periph_driver/src/n32h49x_iwdg.c 实现上述 7 个函数:写访问密钥序列、写入预分频与重载值、重载与启动计数器、运行时冻结与状态读取
projects/n32h49x_EVAL/examples/IWDG/ IWDG 示例根目录,含 IWDG_Reset 1 个示例
projects/n32h49x_EVAL/examples/IWDG/IWDG_Reset/ 该示例的工程目录组成:MDK-ARM/、EWARM/、inc/、src/、readme.txt
projects/n32h49x_EVAL/bsp/ 该示例引用的公共板级文件:串口日志与毫秒延时函数

5.18.2 API 参考

搜索 API共 7 个函数

以下 7 个公开函数按 n32h49x_iwdg.h 的声明顺序分为 3 组;每个条目给出功能摘要与 n32h49x_iwdg.c 中该函数正上方的注释原文。

配置与重载

IWDG_WriteConfig、IWDG_SetPrescalerDiv、IWDG_CntReload、IWDG_ReloadKey

使能与冻结

IWDG_Enable、IWDG_Freeze_Enable

状态

IWDG_GetStatus

void IWDG_WriteConfig(IWDOG_WRITE_CONFIG IWDG_WriteAccess)使能或禁止对 IWDG_PREDIV 与 IWDG_RELV 寄存器的写保护。
源码注释
name    IWDG_WriteConfig.
fun     Enables or disables write protection to IWDG_PREDIV and IWDG_RELV registers.
param   IWDG_WriteAccess
        - IWDG_WRITE_ENABLE
        - IWDG_WRITE_DISABLE
return  none

使用提示: 实现把参数值直接写入 IWDG->KEY;IWDG_WRITE_ENABLE 取值为 0x5555,用于打开 IWDG_PREDIV、IWDG_RELV 的写访问,IWDG_WRITE_DISABLE 取值为 0x0000。

void IWDG_SetPrescalerDiv(uint8_t IWDG_Prescaler)IWDG_Prescaler 指定 IWDG 的预分频值。
源码注释
name    IWDG_SetPrescalerDiv.
fun     IWDG_Prescaler specifies the IWDG prescaler value.
param   IWDG_Prescaler :
          - IWDG_PRESCALER_DIV4
          - IWDG_PRESCALER_DIV8
          - IWDG_PRESCALER_DIV16
          - IWDG_PRESCALER_DIV32
          - IWDG_PRESCALER_DIV64
          - IWDG_PRESCALER_DIV128
          - IWDG_PRESCALER_DIV256
return  none
void IWDG_CntReload(uint16_t Reload)设置 IWDG 重载值。
源码注释
name    IWDG_CntReload.
fun     Sets IWDG reload value.
param   Reload :
          -0x000 ~ 0xFFF
return  none
void IWDG_ReloadKey(void)用 IWDG_RELV 寄存器中定义的值重新加载 IWDG 计数器。
源码注释
name    IWDG_ReloadKey.
fun     Reload IWDG counter with value defined in IWDG_RELV register.
param   none
return  none
void IWDG_Enable(void)启动看门狗计数器。
源码注释
name    IWDG_Enable.
fun     Start watch dog counter.
param   none
return  none
void IWDG_Freeze_Enable(FunctionalState Cmd)在运行模式下 IWDG 运行时冻结或解冻 IWDG。
源码注释
name    IWDG_Freeze_Enable.
fun     Freeze or unfreeze IWDG while IWDG is running in run mode.
param  Cmd :
          - ENABLE
          - DISABLE
return  none

使用提示: 实现按 Cmd 写入 IWDG->KEY:ENABLE 写 0x4567 冻结计数器,其余值写 0x89AB 解冻。

FlagStatus IWDG_GetStatus(IWDG_STATUS_FLAG IWDG_FLAG)检查指定的 IWDG 标志是否置位。
源码注释
name    IWDG_GetStatus.
fun     Checks whether the specified IWDG flag is set or not.
param   IWDG_FLAG :
          - IWDG_PVU_FLAG
          - IWDG_CRVU_FLAG
          - IWDG_FRZF_FLAG
return  FlagStatus :
          - RESET
          - SET

5.18.3 Demo 示例说明

本节说明 IWDG 的 1 个示例:IWDG_Reset 配置 IWDG 超时并在主循环中定期喂狗,用于演示喂狗超时触发的系统复位。

5.18.3.1 IWDG_Reset IWDG 复位

工程目录: projects/n32h49x_EVAL/examples/IWDG/IWDG_Reset/

初始化串口日志与指示灯→检查上次复位是否由 IWDG 触发并点亮 LED1→打开写访问、配置预分频与重载值→启动 IWDG 计数器→主循环翻转 LED3、延时后重载计数器

项目 源码解读
功能 配置 IWDG 计数器时钟为 LSI/32、超时约 250 ms,主循环每 249 ms 重载一次计数器;
正常运行时 LED3 持续闪烁,喂狗超时会触发 IWDG 复位,复位后点亮 LED1 并在串口打印 reset by IWDG。
源码组成 src/main.c:main 与 LedInit、LedOn、LedOff、LedBlink,以及 LSI_TIM_MEASURE 下的 GTIM1_ConfigForLSI;
inc/main.h:包含 n32h49x_iwdg.h、n32h49x_usart.h、misc.h、log.h;
src/n32h49x_it.c、inc/n32h49x_it.h:中断服务函数(含 GTIM1_IRQHandler);
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程。
关键配置 时钟:IWDG 由 LSI 驱动,预分频 IWDG_PRESCALER_DIV32;
重载值:IWDG_CntReload(LsiFreq / 128),LsiFreq 取 32000 Hz,超时约 250 ms;
写访问:IWDG_WriteConfig(IWDG_WRITE_ENABLE) 打开 IWDG_PREDIV、IWDG_RELV 写访问;
指示灯:LED1 为 PA3、LED3 为 PA8,推挽输出。
程序与数据路径 main 调用 log_init,初始化并熄灭 LED1、LED3;
检查 RCC_FLAG_IWDGRSTF:置位时点亮 LED1、打印 reset by IWDG 并清除复位标志,否则熄灭 LED1;
随后 IWDG_WriteConfig、IWDG_SetPrescalerDiv、IWDG_CntReload、IWDG_ReloadKey、IWDG_Enable 依次配置并启动 IWDG;
while(1) 中翻转 PA8(LED3)、延时 249 ms,再用 IWDG_ReloadKey 重载计数器。
主要 API IWDG_WriteConfig、IWDG_SetPrescalerDiv、IWDG_CntReload、IWDG_ReloadKey、IWDG_Enable
验证方法 编译下载并复位运行后 LED3 约每 249 ms 翻转、持续闪烁,说明喂狗正常;
把 systick_delay_ms 的参数改为 251 及以上使喂狗超时,系统将持续复位、LED1 点亮,串口打印 reset by IWDG。
使用提示 硬件开发环境为全功能板 N32H497ZGL7_EVB V1.0;
开发环境为 KEIL MDK-ARM 5.34 或 IAR EWARM 8.50.1;
未定义 LSI_TIM_MEASURE 时超时值直接取 LsiFreq / 128,不测量实际 LSI 频率,实际超时会随 LSI 频率离散略有偏差。
核心代码解读与移植

示例先检测本次复位是否来自 IWDG,再依次完成写访问、预分频、重载与启动,最后在主循环中定期喂狗。

数据路径: RCC_FLAG_IWDGRSTF 复位标志 → IWDG_WriteConfig、IWDG_SetPrescalerDiv、IWDG_CntReload、IWDG_Enable 写入 IWDG_PREDIV、IWDG_RELV 与 IWDG_KEY → 主循环 IWDG_ReloadKey 重载计数器 → LED3 翻转、复位时 LED1 点亮

1. 初始化并点亮指示灯。 main 先调用 log_init,把 LED1(PA3)与 LED3(PA8)初始化为推挽输出并熄灭。

src/main.csrc/main.c · main
    log_init();
    log_info("--- IWDG demo reset ---\n");
    LedInit(LED1_GPIO_PORT, LED1_GPIO_PIN);
    LedInit(LED3_GPIO_PORT, LED3_GPIO_PIN);
    LedOff(LED1_GPIO_PORT, LED1_GPIO_PIN);
    LedOff(LED3_GPIO_PORT, LED3_GPIO_PIN);

移植到其它板卡时改 LED1_GPIO_PORT、LED1_GPIO_PIN、LED3_GPIO_PORT、LED3_GPIO_PIN 这组宏即可,LED 初始化与 IWDG 本身无关。

2. 检查复位来源并显示。 先使能 PWR 时钟,再读取 RCC_FLAG_IWDGRSTF:若本次复位由 IWDG 触发就点亮 LED1、打印提示并清除复位标志,否则熄灭 LED1。

src/main.csrc/main.c · main
    /* Check if the system has resumed from IWDG reset */
    if(RCC_GetFlagStatus(RCC_FLAG_IWDGRSTF) != RESET)
    {
        /* IWDGRST flag set */
        /* Turn on LED1 */
        LedOn(LED1_GPIO_PORT, LED1_GPIO_PIN);
        log_info("reset by IWDG\n");
        /* Clear reset flags */
        RCC_ClearResetFlag();
    }
    else
    {
        /* IWDGRST flag is not set */
        /* Turn off LED1 */
        LedOff(LED1_GPIO_PORT, LED1_GPIO_PIN);
    }

移植时要保留清除复位标志的调用,否则下一次上电仍会读到旧的复位来源;读取该标志前需使能 PWR 时钟。

3. 配置并启动 IWDG。 main 先打开写访问,再写入预分频与重载值,然后重载并启动计数器。

src/main.csrc/main.c · main
    /* IWDG timeout equal to 250 ms (the timeout may varies due to LSI frequency
       dispersion) */
    /* Enable write access to IWDG_PR and IWDG_RLR registers */
    IWDG_WriteConfig(IWDG_WRITE_ENABLE);

    /* IWDG counter clock: LSI/32 */
    IWDG_SetPrescalerDiv(IWDG_PRESCALER_DIV32);

    /* Set counter reload value to obtain 250ms IWDG TimeOut.
       Counter Reload Value = 250ms/IWDG counter clock period
                            = 250ms / (LSI/128)
                            = 0.25s / (LsiFreq/32)
                            = LsiFreq/(32 * 4)
                            = LsiFreq/128 */
    log_debug("LsiFreq is: %d\n", LsiFreq);

    IWDG_CntReload(LsiFreq / 128);
    /* Reload IWDG counter */
    IWDG_ReloadKey();

    /* Enable IWDG (the LSI oscillator will be enabled by hardware) */
    IWDG_Enable();

LsiFreq 默认为 32000 Hz,配合预分频 IWDG_PRESCALER_DIV32 得到约 250 ms 超时;改超时时间要同时核对预分频因子与 IWDG_CntReload 的参数。

4. 主循环定期喂狗。 循环里翻转 LED3、延时 249 ms,再调用 IWDG_ReloadKey 重载计数器。

src/main.csrc/main.c · main
    while(1)
    {
        /* Toggle LED3 */
        LedBlink(LED3_GPIO_PORT, LED3_GPIO_PIN);
        /* Insert 249 ms delay */
        systick_delay_ms(249);
        /* Reload IWDG counter */
        IWDG_ReloadKey();
    }

喂狗间隔须小于超时时间(这里 249 ms 小于 250 ms);把延时改到超时以上会触发 IWDG 复位。

对应源码: src/main.c

5.18.4 注意与排障

场景 检查与建议 来源
修改预分频与重装载值 这两个寄存器带写保护,需先向 IWDG_KEY.KEYV[15:0] 写入 0x5555 打开写访问;
写入其他值会重新启用写保护,重载操作(写 0xAAAA)也会使寄存器再次变为写保护。
用户手册
更新标志未清零 修改预分频前须确认 IWDG_STS.PVU 为 0、修改重载值前须确认 IWDG_STS.CRVU 为 0;
更新期间读取 IWDG_PREDIV.PD[2:0] 或 IWDG_RELV.REL[11:0] 无效。
用户手册
启用方式 向 IWDG_KEY.KEYV[15:0] 写入 0xCCCC 启动计数器;
通过选项字节使能硬件看门狗后,上电即自动运行。
用户手册
复位使能位 PWR_CTRL2.IWDGRSTEN 为 1 时计数器到 0 产生系统复位;
该位为 0 时 IWDG 会计数但不产生复位。
用户手册
调试模式 内核停止时 IWDG 计数器是否停止由调试模块的 DBG_CTRL.IWDG_STOP 位决定:该位为 1 时计数器停止,为 0 时继续计数。 用户手册
停止计数 一旦 IWDG 使能,除非发生系统复位或向 IWDG_KEY.KEYV[15:0] 写入 0x4567 配置运行时冻结,IWDG 不会停止计数。 用户手册
国民技术开发套件文档中心

按芯片系列在线查阅国民技术 MCU 开发套件的芯片资料、SDK、驱动 API 与 Demo 示例说明。

© 2026 国民技术股份有限公司 版权所有粤ICP备11069485号本站使用不含 Cookie 的匿名访问统计