【STM32】独立看门狗(IWDG)原理详解及编程实践(下)
这篇文章详细讲解独立看门狗的编程实践代码。关于独立看门狗的原理及配置可以看上一篇文章。
【STM32】独立看门狗(IWDG)原理详解及编程实践(上)-CSDN博客
目录
1、 初始化 IWDG
2. 配置 IWDG
3. 喂狗
4. 处理看门狗复位
5、完整示例,展示如何在STM32中配置和使用IWDG
6、标准库版本
1、 初始化 IWDG
#include "stm32f4xx_hal.h"
// 初始化独立看门狗
void IWDG_Init(void) {
// 使能IWDG的时钟
__HAL_RCC_WWDG_CLK_ENABLE();
// 启动IWDG
HAL_IWDG_Init(&hiwdg);
}
2. 配置 IWDG
配置看门狗的计时周期等参数。以STM32为例,通常在初始化时就进行配置。
#include "stm32f4xx_hal.h"
// 配置IWDG
void IWDG_Config(void) {
// 设置独立看门狗预分频器和计数器重装值
// 这里的配置可能会根据具体型号有所不同
HAL_IWDG_Init(&hiwdg);
}
3. 喂狗
在程序的主循环中定期喂狗,以防止看门狗超时复位系统。通常会在关键的代码区域或任务中调用。
// 定期喂狗,避免看门狗超时
void Feed_Watchdog(void) {
HAL_IWDG_Refresh(&hiwdg);
}
4. 处理看门狗复位
如果系统由于某种原因没有正确地喂狗,看门狗会触发复位。通常在系统启动时,你可以检查是否由于看门狗复位而重新启动系统。
void System_Init(void) {
// 检查系统是否是由看门狗复位引起的
if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET) {
// 处理看门狗复位情况
__HAL_RCC_CLEAR_RESET_FLAGS();
}
// 其他初始化代码
}
5、完整示例,展示如何在STM32中配置和使用IWDG
#include "stm32f4xx_hal.h"
// IWDG句柄
IWDG_HandleTypeDef hiwdg;
// 初始化IWDG
void IWDG_Init(void) {
// 配置IWDG
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_64; // 设置预分频器
hiwdg.Init.Reload = 4095; // 设置重装载值
HAL_IWDG_Init(&hiwdg);
}
// 主函数
int main(void) {
HAL_Init();
SystemClock_Config(); // 配置系统时钟
IWDG_Init(); // 初始化IWDG
while (1) {
// 你的主循环代码
Feed_Watchdog(); // 定期喂狗
// 添加延时,模拟主循环工作
HAL_Delay(100);
}
}
注意事项
- 时钟源选择:IWDG通常使用内部低速振荡器(LSI)作为时钟源,该时钟源在系统复位时也会保持运行。不同的单片机可能有不同的配置方式。
- 复位后处理:如果系统由于看门狗复位而重新启动,通常需要在系统初始化时检查并清除相关复位标志。
- 配置参数:确保按照单片机的技术手册正确设置看门狗的预分频器和重装载值,以便根据应用需求进行适当的配置。
6、标准库版本
#include "stm32f10x.h" // 包含 STM32F10x 系列的头文件
void IWDG_Init(uint16_t prescaler, uint16_t reload_value) {
// 使能 IWDG 时钟(对于 STM32F10x 系列,需要确保 IWDG 时钟源已开启)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
// 解锁 IWDG
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
// 设置 IWDG 预分频器
IWDG_SetPrescaler(prescaler);
// 配置 IWDG 重新加载值
IWDG_SetReload(reload_value);
// 启动 IWDG
IWDG_ReloadCounter();
IWDG_Enable();
}
void IWDG_Feed(void) {
// 喂狗,防止看门狗复位
IWDG_ReloadCounter();
}
int main(void) {
// 系统初始化代码
// ...
// 初始化独立看门狗
IWDG_Init(IWDG_Prescaler_64, 0xFFF); // 配置 IWDG 预分频器为 64,重新加载值为 0xFFF
while (1) {
// 主循环代码
// ...
// 喂狗,防止看门狗复位
IWDG_Feed();
// 其他操作,例如延时
for (volatile int i = 0; i < 1000000; i++);
}
}
IWDG_Init 函数
- RCC_APB1PeriphClockCmd: 使能 IWDG 时钟。确保 IWDG 的时钟源已经开启。
- IWDG_WriteAccessCmd: 解锁 IWDG 以进行配置。需要调用
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable)
来允许对 IWDG 的写访问。- IWDG_SetPrescaler: 设置 IWDG 预分频器。这决定了 IWDG 的计时周期。预分频器的选项如
IWDG_Prescaler_4
,IWDG_Prescaler_8
,IWDG_Prescaler_16
,IWDG_Prescaler_32
,IWDG_Prescaler_64
。- IWDG_SetReload: 设置 IWDG 的重新加载值。这决定了超时时间。
- IWDG_ReloadCounter: 重新加载 IWDG 计数器,以防止看门狗复位。
- IWDG_Enable: 启动 IWDG。配置完成后,需要调用
IWDG_Enable
来使能 IWDG。IWDG_Feed 函数
- IWDG_ReloadCounter: 定期调用以重载计数器,防止看门狗超时复位。
main 函数
- 调用 IWDG_Init 初始化 IWDG。
- 在主循环中定期调用 IWDG_Feed,以确保系统正常运行时不会触发看门狗复位。