返回列表 发新帖我要提问本帖赏金: 60.00元(功能说明)

[MM32生态] 喂狗?为什么IWDG和WWDG里起这么奇怪的名字?开发过程在这里

[复制链接]
2519|7
 楼主| 春娇霹雳娃 发表于 2023-7-28 17:58 | 显示全部楼层 |阅读模式
本帖最后由 春娇霹雳娃 于 2023-8-16 17:35 编辑

#申请原创# @21小跑堂
本实验基于MM32F0040实现IWDG和WWDG工程开发工作。

1.开发板简介
MM32F0040使用高性能的 Arm® Cortex-M0 为内核的 32 位微控制器,最高工作频率可达 72MHz,内置高速存储器,其硬件外观如下图所示:
6248964c3862df0f00.png
电路图如下:
5484964c3869ef2ddd.png

2.功能描述
2.1 IWDG

IWDG(Independent Watch Dog),为检测和解决由软件错误所引起的故障而设计。独立看门狗(IWDG)适用于需要看门狗作为一个处于主程序之外,能够完全独立工作,适用于对时间精度要求低的需求场景中。IWDG分为两种工作模式:
  • 硬件独立看门狗
  • 软件独立看门狗(默认为软件独立看门狗模式)

功能框图如下:
261564c38a77cf390.png

本质:可理解为一个12位递减计数器,当计数器的值从装载的值一直递减到零时,向系统触发复位信号,即IWDG_RESET。在计数器递减到零之前,重新装置计数器内的值,则不会产生复位信号,重置计数器值的操作即为“喂狗”。
“喂狗” 分为两种方式:
  • 直接重载初始化设定值
  • 重新设定重载值

2.2 WWDG
WWDG(Window Watchdog Timer)窗口看门狗,一种七位向下计数的timer,计数范围0x7F~0x3F(计数到0x3F将发出复位请求)。喂狗操作:通过更新计数器WWDG_CR[T]计数值,避免计数器向下计数到0x3F,实现“喂狗”操作。
有上下限的喂狗(IWDG只有下限)
  • 上限:寄存器WWDG_CFGR[W]配置值,如果计数值大于此配置值时“喂狗”,则WWDG向CPU发出复位请求(提前“喂狗”)
  • 下限:0x3F(不可修改),如果计数值计数到0x3F,则WWDG向CPU发出复位请求(没有“喂狗”)

作用:
  • 当程序运行偏离了正常的程序路径,能够及时发出复位请求
  • 程序运行偏离了正常的程序路径,提前执行了“喂狗”操作,也能及时发出复位请求
6127364c38cedf3efe.png
WWDG功能框图如下:
9823064c38cfe8293d.png
WWDG使用范围:
1.用于程序执行时间精度要求较高的场景
  • 通过APB时钟分频作为计数器时钟来源,计数时钟可精确计算
  • 具有上下限的喂狗窗口范围,避免过早喂狗使喂狗失效
2.喂狗时间范围极小
  • 当APB1时钟频率为60MHz时,最晚30毫秒内就需要喂狗一次
3.能否在低功耗状态下使用
  • WWDG的计数时钟来源于APB时钟的分频
  • 如果APB时钟关闭,WWDG则无法继续计数,因此WWDG无法在低功耗状态下使用。
2978364c38d5e1809f.png

3.寄存器配置
3.1 IWDG
iwdg 受访问保护的寄存器有:
  • IWDG_PR
  • IWDG_CR
  • IWDG_IGEN
  • IWDG_RLR

上述四个寄存器受访问保护。若要修改其中任一寄存器,须先对 IWDG_KR寄存器写入解锁值( 0x5555),写入后四个寄存器将同时被解除访问保护。当IWDG_KR被写入除0x5555外的值时,上述四个寄存器将同时都被锁定。如重装载操作(即“喂狗”)也会对上述四个寄存器启动访问保护功能。

预分频系数设置:
6661464c38b393011a.png

IWDG 实现思路:
  • 初始化IWDG
  • 开启LSI时钟
  • 设置IWDG预分频系数
  • 设置IWDG重载值
  • IWDG溢出配置
  • 更新IWDG重载值
  • 使能IWDG
  2. 更新重载值
  • 方法一:通过IWDG_KG直接重载初定值
  • 方法二: 重新设定重载值
  3. 中断配置
  • 使能IWDG中断
  • 失能IWDG中断(仅能在初始化阶段使用)
  • 配置IWDG中断触发值
  • 获取IWDG中断状态
  • 清除IWDG中断
7211664c38bc2e9f9f.png

3.2 WWDG
WWDG实现思路:
1.启动WWDG
  • 开启WWDG的RCC时钟
  • 初始化WWDG,包括配置时基和重装载窗口值
  • 使能WWDG,计数器开始计数
  • 使能WWDG_INT_EW中断(可选)
2.喂狗
  • 在规定时间内重装载计数值“喂狗”,提前或超时重装载计数值将产生复位请求
3.中断
  • 使能WWDG_INT_EW中断后,计数器计数到0x40产生中断
4.复位
  • WWDG产生复位请求后,CPU响应复位请求产生复位,复位后RCC_CSR[WWDGRSTF]置位
  • MCU复位后,可通过查看RCC_CSR[WWDGRSTF]标志位确定是否为窗口看门狗复位

4.软件实现
4.1 IWDG
启动检测,若为独立看门口复位,则通过UART输出本次启动为独立看门口复位,若非独立看门狗复位,则通过UART输出本次启动为正常启动或其他复位。开启时钟LSI , 配置IWDG的预分频系数为 32,重载值为 0x1F,初始化独立看门狗功能。在主函数中循环喂狗10次后停止喂狗。停止喂狗,则等待计数器溢出,独立看门狗触发复位信号。
主函数:
  1. int main(void){
  2.     uint32_t i = 0;

  3.     BOARD_Init();
  4.     printf("iwdg_basic example.\r\n");

  5.     app_iwdg_init();

  6.     for(i = 0; i < 10; i++){
  7.         /* Reload the IWDG counter. */
  8.         IWDG_DoReload(BOARD_IWDG_PORT);
  9.         printf("Feed dog count: %u\r\n", (unsigned)(i+1) );
  10.         app_soft_delay(200);}

  11.     /* Waiting for MCU reset. */
  12.     while(1){}}
配置IWDG
  1. /* IWDG. */
  2. #define BOARD_IWDG_PORT              IWDG
  3. #define BOARD_IWDG_RELOAD            0x7ff //0x3ff
  4. #define BOARD_IWDG_PRESCALER         IWDG_Prescaler_32
初始化:
  1. void IWDG_Init(IWDG_Type * IWDGx, IWDG_Init_Type * init)
  2. {   
  3.     if ( NULL != init )
  4.     {
  5.         IWDGx->KR = IWDG_KEY_UNLOCK;   
  6.         IWDGx->PR = init->Prescaler;
  7.         
  8.         IWDGx->KR = IWDG_KEY_UNLOCK;
  9.         IWDGx->RLR = init->Relaod;

  10.         IWDG_DoReload(IWDGx);
  11.     }
  12. }
使能IWDG
  1. void IWDG_Start(IWDG_Type * IWDGx)
  2. {
  3.     IWDGx->KR = IWDG_KEY_ENABLE;
  4. }
重载IWDG
  1. void IWDG_DoReload(IWDG_Type * IWDGx)
  2. {
  3.     IWDGx->KR = IWDG_KEY_RELOAD;
  4. }
开启中断
  1. void IWDG_EnableInterrupts(IWDG_Type * IWDGx, uint32_t interrupts, bool enable)
  2. {
  3.     if( (true == enable ) && (IWDG_INT_ALMOST_TIMEOUT == interrupts) )
  4.     {
  5.         IWDGx->CR |= IWDG_CR_IRQSEL_MASK;
  6.     }
  7.     else
  8.     {
  9.         /* if IWDG_EnableInterrupts interrupt was enabled, only MCU reset can close it. */
  10.     }
  11. }

4.2 WWDG
1.初始化WWDG_Init():
  • 配置计数器的计数时基(分频系数)TimeBase
  • 配置“喂狗”重装载窗口值(喂狗上限)ReloadWindow
2.使能WWDG_Enable():
  • 使能WWDG,使计数器开始计数
  • 使能WWDG后,只有复位才能关闭WWDG。
3.重装载计数值WWDG_Reload():
  • 重装载计数值,实现“喂狗”操作
  • 重装载计数值后,计数器从新的计数值开始向下计数
4.中断
  • 提前唤醒中断WWDG_INT_EW,当计数器计数到0x40时发出,通知CPU即将发出复位请求。
  • 同使能WWDG一样,使能提前唤醒中断WWDG_INT_EW后只有复位才能关闭此中断。
初始化:
  1. void WWDG_Init(WWDG_Type * WWDGx, WWDG_Init_Type * init)
  2. {
  3.     if (NULL != init)
  4.     {
  5.         WWDGx->CFGR = WWDG_CFGR_WDGTB(init->Prescaler)
  6.                     | WWDG_CFGR_W(init->UpperLimit);
  7.     }
  8. }
使能WWDG
  1. void WWDG_Start(WWDG_Type * WWDGx)
  2. {
  3.     WWDGx->CR |=  WWDG_CR_WDGA_MASK;
  4. }
重载WWDG
  1. void WWDG_Reload(WWDG_Type * WWDGx, uint32_t value)
  2. {
  3.     if (value > WWDG_LOWER_LIMIT)
  4.     {
  5.         WWDGx->CR = (WWDGx->CR & ~WWDG_CR_T_MASK) | WWDG_CR_T(value);
  6.     }
  7. }
中断唤醒
  1. void WWDG_EnableInterrupts(WWDG_Type * WWDGx, uint32_t interrupts, bool enable)
  2. {
  3.     if ( (true == enable) && (WWDG_INT_ALMOST_TIMEOUT == interrupts) )
  4.     {
  5.         WWDGx->CFGR |= WWDG_CFGR_EWI_MASK;
  6.     }
  7.     else
  8.     {
  9.         /* if WWDG_INT_ALMOST_TIMEOUT interrupt is enabled, only MCU reset can close it. */
  10.     }
  11. }
配置中断
  1. /* WWDG */
  2. #define BOARD_WWDG_PORT              WWDG
  3. #define BOARD_WWDG_IRQn              WWDG_IWDG_IRQn
  4. #define BOARD_WWDG_IRQHandler        WWDG_IWDG_IRQHandler
  5. #define BOARD_WWDG_UPPER_LIMIT       0x7fu
  6. #define BOARD_WWDG_RELOAD_TIMES      100u
  7. #define BOARD_WWDG_RELOAD_VALUE      0x7fu
  8. #define BOARD_WWDG_PRESCALER         WWDG_Prescaler_8
开启时钟
  1. /* WWDG. */
  2.     RCC_EnableAPB1Periphs(RCC_APB1_PERIPH_WWDG, true);
  3.     RCC_ResetAPB1Periphs(RCC_APB1_PERIPH_WWDG);
主函数:
  1. int main(void)
  2. {
  3.     BOARD_Init();
  4.     printf("\r\nwwdg_basic example.\r\n");

  5.     /* Setup WWDG. */
  6.     app_wwdg_init();

  7.     while (1)
  8.     {
  9.         putchar('.');
  10.         app_soft_delay(100);
  11.     }
  12. }

5.实验现象
iwdg_basic


wwdg_basic


6.附件
原理图: Mini-F0040_SCH.pdf (314.04 KB, 下载次数: 0)
工程文件: mini-f0040_iwdg_basic_mdk.zip (510.03 KB, 下载次数: 0) mini-f0040_wwdg_basic_mdk.zip (510.23 KB, 下载次数: 0)



打赏榜单

21小跑堂 打赏了 60.00 元 2023-08-09
理由:恭喜通过原创审核!期待您更多的原创作品~

评论

对比介绍IWDG和WWDG两种单片机外设,原理介绍清晰,实现过程较好,值得借鉴  发表于 2023-8-9 15:44
 楼主| 春娇霹雳娃 发表于 2023-7-31 17:43 | 显示全部楼层
 楼主| 春娇霹雳娃 发表于 2023-8-10 11:13 | 显示全部楼层
zwll 发表于 2023-8-10 20:56 | 显示全部楼层
密码帖?
 楼主| 春娇霹雳娃 发表于 2023-8-15 09:32 | 显示全部楼层
单片小菜 发表于 2023-8-16 16:45 | 显示全部楼层
密码贴是啥意思?
 楼主| 春娇霹雳娃 发表于 2023-8-16 17:31 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:灵动系统开发工程师
简介:none........

19

主题

154

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部