本网页已闲置超过3分钟,按键盘任意键或点击空白处,即可回到网页
最热资讯


亲,“电路城”已合并升级到更全、更大、更强的「新与非网」。点击查看「新与非网」
STM32F401xD/E 有两个监视器定时器——独立监视器(IWDG)和窗口监视器(WWDG)。在该项目中,将看到如何激活和定期刷新监视器。
监视器是监视 MCU 上运行的应用程序,如果程序执行的正常顺序出现异常 - 软件故障,监视器会检测到它。然后启动 MCU 复位,这将有助于重新启动软件。
从功能的角度来看,IWGD 和 WWDG 之间有两个主要区别。
与 IWDG 不同,WWDG 由 APB1 外设时钟提供时钟。
在该项目中,将配置和测试以下案例:
项目建立:
1、从板选择器在 STM32CubeMX 中创建一个项目
2、在左侧窗格中,展开 - System Core 并选择 - WWDG,出现窗口,显示 WWDG 配置。在窗口单击已激活,这将使用默认配置激活 WWDG,
WWDG 计数器时钟预分频器:时钟的结果值等于 (PCLK1/4096)/预分频器
[预分频器只是一个时钟分频器,预分频器越高,计数器的时钟频率就越低,因此计数需要更长的时间]
选择预分频器为 8:(PCLK1/4096)/ 8
这导致递减计数器的 WWDG 时钟为 (42MHz/4096)/8 = 1281.738 Hz。因此时钟周期(1 个时钟周期)约为780us
tClkWwdg = 780us
Window:WWDG 中的这个术语是指允许刷新监视器的时间范围。超出此区域被解释为软件故障,并且 MCU 复位由 WWDG 启动。
(STM32F401RE参考手册中的WWDG时序图)
3 个参数定义了窗口:
当down counter值大于W[6:0]且小于0x3F时,为WWDG提供服务(刷新/更新)。未能在此窗口中刷新将被WWDG解释为软件故障并启动重置。
为监视器窗口选择值:预分频器 = 8;W=94;T = 127。
计算时间:
倒计时计数器从127倒计时到63所用的时间:tWWDG=tClkWWDG*(127-63)=49.92ms
从下行计数器127开始到到达94,不允许刷新,即 tNoRefr=tClkWWDG*(127-94)=25.74ms
允许在tNoRefr之后和tWWDG之前刷新。
回到CubeMX,切换到projectmanager透视图并选择keilmdk,保存项目并点击“generatecode”。
注监视器中断(早期唤醒中断-EWI)保持禁用状态
(STM32CUBEMX项目经理视角)
选择 Open project 并打开 Keil MDK IDE, main.c 文件。
构建项目并查看有无错误
右键单击监视器init 函数并选择转到定义:static void MX_WWDG_Init(void);
注,参数与 CubeMX 中指定的一样
可随意查看源文件(stm32f4xx_it.c),用于 EXTI(外部中断/事件控制器)例程。
构建项目并将其添加到 ST32F401RE Nucleo 板即可。
情况1:
由于还没有为 WWDG 提供服务,当递减计数器达到 0x3F 后,将触发 MCU 复位。将Digilent Analog Discovery 的示波器通道 1 连接到复位线并对其进行监控。
预期:WWDG 每大约 50 毫秒触发一次重置。
CN4- Pin 5 is NRST
(原理图)
打开 Digilent 波形
构建项目并点击调试按钮,从RCC外围设备监控CRC寄存器
代码仍处于暂停状态,清除所有重置,然后继续进行一个设置:
Click RMVF bit
Hit 运行(F5)启动程序
WWDGRSTF设置完毕。
如预期复位线切换每约52毫秒。
情况2:
刷新WWDG,转到main.c,
将以下代码包含在无限 while 循环中:
HAL_Delay(30); // 将 MCU 暂停 30 毫秒,等待 30ms 并刷新 WWDG
HAL_WWDG_Refresh(&hwwdg);
WWDG 触发了重置,需重新构建项目并在调试模式下打开,设置 RMVF 位以清除复位标志并运行程序,可看到 WWDGRSTF 标志始终清晰。
情况3:
提前刷新WWDG并检查是否触发了重置。
需将延迟值从 30ms 修改为小于 tNoRefr (25.74ms) 的值,如15ms
由于很快就会刷新 WWDG,因此每 18 ms触发一次重置。
情况4:
WWDG在触发休息之前会产生一个中断,这有助于在安全的状态下退出,如拍摄系统快照并存储到 EEPROM 中。通过启用 EWI 中断来检查此功能,并编写一个例程来切换板载绿色 LED。
在示波器上观察到在启动 MCU 复位之前执行了 ISR。这是 WWDG 中的一项高级功能,在 IWDG 中不可用。
可以使用 CubeMX 以图形方式启用 EWI
需在 NVIC 设置中启用监视器中断。如果不启用全局监视器中断,仅启用 EWI 将不起作用,因为中断将无法通过中断控制器-NVIC。
保存项目并构建,切换回 Keil 时,会提示你是否更新了文件以及是否要加载它们,选择是
Keil 项目中应该有最新的文件,转到文件 stm32f4xx_it.c。将在最后看到添加了这段额外的代码(在红色框中),它是 WWDG 中断处理程序。
转到 蓝色框中指示的定义 HAL_WWDG_IRQHandler(&hwwdg);
可以看到启用了提前唤醒回调,并创建了 __weak 函数。复制该函数并将其粘贴到 main.c 中并删除 __weak。这是编写例程来切换板载绿色 LED 以查看是否在启动重置之前执行 ISR 的地方,指示必须在 main.c 中复制它的位置。在所有外设初始化函数完成后以及用户代码开始和结束之间执行此操作。
从函数体中删除所有内容并切换板载 LED。
注释掉 while(1) 无限循环中编写的代码,将让递减计数器过去,并期望 WWDG 重置 MCU。但在此之前,我们希望它为我们的中断服务。我们将通过每 20 毫秒切换一次 LED 进行监控。
请按照与之前相同的步骤构建项目并在调试模式下打开它。设置 RMVF 位以清除复位标志并运行程序。
显示切换板载绿色 LED :
示波器:
Ch1:NRST
Ch2:LED
可以看到中断是生成的。复位前 780us,正好是前一个 WWDG 时钟周期。但是重置每 52ms 触发一次,即仅在向下计数器向下计数到 0x3F(十进制:63)之后。
已经在各种场景下配置并测试了STM32F401RE的Window的监视器,在情况4中,可以看到
板载 LED 不会每 20 毫秒切换一次。复位迫使 LED 关闭,因为 WWDG 只给 MCU 1 个时钟周期来做任何重要的事情。由于重置每 52 毫秒发生一次,我们可能会将 LED 切换误解为我们的 ISR 例程。事实上,HAL_GPIO_TogglePin()甚至还没有完全执行。它被重置破坏了。尝试注释掉HAL_Delay(),尝试替换HAL_GPIO_TogglePin()为HAL_GPO_WritePin(),看看会发生什么。
同样在启用 EWI 的情况下,尝试过早刷新 WWDG 并查看是否执行了 ISR。
附:
示意图:
代码:
讨论