单片机STM32看门狗
- 什么是看门狗
- 为什么需要看门狗?
- STM32CubeMX配置和应用
- 示例
- 独立看门狗(IWDG)
- 窗口看门狗(WWDG)
- 注意事项
什么是看门狗
单片机STM32的看门狗(Watchdog)是一种硬件定时器,用于监控系统的运行状态并在出现故障或死锁时采取措施以恢复正常操作。看门狗的主要功能是定期检查系统是否正常运行,并在系统出现问题时触发复位操作。
STM32系列单片机通常配备了内置的看门狗定时器(通常称为独立看门狗,IWDG)和窗口看门狗定时器(WWDG),以提供更可靠的系统保护。
独立看门狗(IWDG)是STM32中常用的看门狗,它是一个独立的硬件模块,可以在系统内部独立运行。通过配置IWDG定时器的计数器和预分频器,可以设置看门狗的定时时间。当看门狗定时器计数器达到预设的值时,会产生看门狗超时事件,触发系统复位。
窗口看门狗(WWDG)是另一种类型的看门狗,它允许在特定的时间窗口内更新计数器值,以避免触发复位。WWDG可以通过设定窗口和计数器的值来进行配置,并在每次更新计数器时,确保计数器值位于设定的窗口范围内。如果计数器超出窗口范围,将触发看门狗复位。
通过使用STM32的看门狗功能,可以监测系统运行的正常性,防止系统出现死锁或意外故障导致的无响应状态。看门狗可以在系统软件编程错误、电源干扰或其他异常情况下,提供一个安全机制来恢复系统的正常运行。
为什么需要看门狗?
看门狗在嵌入式系统中起着重要的作用,以下是一些需要看门狗的原因:
-
防止系统死锁:在某些情况下,嵌入式系统可能会陷入无限循环或死锁状态,导致系统停止响应。看门狗能够监测系统的运行状态,如果系统在预定的时间内没有及时更新看门狗定时器,就会触发复位操作,使系统重新启动并恢复正常运行。
-
处理软件故障:在开发嵌入式软件时,可能会出现编程错误、内存溢出、任务优先级错误等问题,导致系统运行不正常。看门狗可以监测系统是否持续运行,并在软件故障时进行复位,以恢复系统到初始状态。
-
应对外部干扰:嵌入式系统可能受到外部干扰,如电源波动、电磁干扰等。这些干扰可能导致系统崩溃或运行不正常。看门狗可以检测这些异常情况,并在系统无响应时采取措施,以确保系统的稳定性和可靠性。
-
提高系统可靠性:通过引入看门狗,系统可以在出现故障时自动恢复,减少系统停机时间。这对于需要连续运行和高可靠性的应用非常重要,如工业控制、汽车电子、医疗设备等领域。
总之,看门狗提供了一种监测和保护机制,确保嵌入式系统的可靠性和稳定性。它可以防止系统死锁、处理软件故障、抵御外部干扰,并提高系统的可用性和可靠性。
STM32CubeMX配置和应用
在使用STM32CubeMX配置和应用看门狗时,您可以按照以下步骤进行操作:
-
打开STM32CubeMX软件,并创建或打开您的工程。
-
在"Pinout & Configuration"选项卡中,选择您的目标STM32微控制器型号。
-
在"Peripherals"面板中,找到并展开"System Core"选项。
-
选择"Independent Watchdog"(独立看门狗)或"Window Watchdog"(窗口看门狗),具体根据您的需求选择相应的看门狗类型。
-
配置看门狗的参数,包括计数器值、预分频器、窗口值等,根据您的应用需求进行设置。您可以在"Configuration"面板中进行配置。
-
在配置完成后,单击"Project"菜单,选择"Settings",然后在"Code Generator"选项中启用看门狗的代码生成。
-
单击"Project"菜单,选择"Generate Code",生成代码并导出到您的工程目录。
-
在您的代码中,可以使用相关的看门狗函数来初始化和操作看门狗。
例如,如果使用独立看门狗(IWDG),则可以使用以下函数进行初始化和操作:
HAL_IWDG_Init()
:初始化独立看门狗,设置计数器和预分频器等参数。HAL_IWDG_Start()
:启动独立看门狗计数器。HAL_IWDG_Refresh()
:刷新独立看门狗计数器,防止看门狗超时复位系统。HAL_IWDG_GetState()
:获取独立看门狗的状态,判断是否发生看门狗超时。
对于窗口看门狗(WWDG),可以使用类似的函数来进行配置和操作。
请注意,以上步骤仅涵盖了基本的配置和应用看门狗的过程。具体的步骤和函数名称可能会根据您所使用的STM32系列和CubeMX版本而有所不同。建议参考官方文档和相应的参考手册以获取更详细的信息和指导。
示例
独立看门狗(IWDG)
以下是使用STM32F103C8T6单片机编写独立看门狗(IWDG)的代码示例:
#include "stm32f1xx_hal.h"
IWDG_HandleTypeDef hiwdg;
void SystemClock_Config(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_4; // 设置预分频器,产生IWDG时钟频率
hiwdg.Init.Reload = 4095; // 设置计数器重装载值,用于设定看门狗超时时间
if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
{
Error_Handler();
}
while (1)
{
HAL_IWDG_Refresh(&hiwdg); // 刷新看门狗计数器,防止看门狗超时复位系统
// 执行其他任务和代码
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
以上代码示例中,主要步骤如下:
-
初始化HAL库和系统时钟。
-
定义
IWDG_HandleTypeDef
类型的变量hiwdg
,用于配置和操作独立看门狗。 -
在
main()
函数中,使用HAL_IWDG_Init()
函数初始化独立看门狗,设置预分频器和计数器重装载值。 -
在主循环中,使用
HAL_IWDG_Refresh()
函数刷新看门狗计数器,防止看门狗超时复位系统。您可以在此处添加其他任务和代码。
请注意,此代码示例中的时钟配置是基于HSI(内部高速时钟)和PLL(锁相环)的基本配置。
窗口看门狗(WWDG)
以下是使用STM32F103C8T6单片机编写窗口看门狗(WWDG)的代码示例:
#include "stm32f1xx_hal.h"
WWDG_HandleTypeDef hwwdg;
void SystemClock_Config(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
hwwdg.Instance = WWDG;
hwwdg.Init.Prescaler = WWDG_PRESCALER_8; // 设置预分频器,产生WWDG时钟频率
hwwdg.Init.Window = 127; // 设置窗口值
hwwdg.Init.Counter = 127; // 设置计数器重装载值
if (HAL_WWDG_Init(&hwwdg) != HAL_OK)
{
Error_Handler();
}
while (1)
{
HAL_WWDG_Refresh(&hwwdg, 127); // 刷新看门狗计数器,并设置窗口值
// 执行其他任务和代码
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
以上代码示例中,主要步骤如下:
-
初始化HAL库和系统时钟。
-
定义
WWDG_HandleTypeDef
类型的变量hwwdg
,用于配置和操作窗口看门狗。 -
在
main()
函数中,使用HAL_WWDG_Init()
函数初始化窗口看门狗,设置预分频器、窗口值和计数器重装载值。 -
在主循环中,使用
HAL_WWDG_Refresh()
函数刷新看门狗计数器,并设置窗口值。您可以在此处添加其他任务和代码。
注意事项
在使用看门狗时,有几个方面需要特别注意:
-
看门狗定时器的配置:确保正确配置看门狗的计数器值、预分频器等参数,以满足您的应用需求和系统稳定性要求。过小的计数器值可能导致系统频繁复位,而过大的计数器值则可能导致看门狗无法及时复位系统。
-
定时刷新看门狗:在主循环或关键任务中,确保及时刷新看门狗,以防止看门狗超时复位系统。刷新看门狗的操作应该在预定的时间范围内完成,否则看门狗将认为系统出现故障。
-
看门狗的启动和停止:确保在适当的时机启动和停止看门狗。通常,在系统初始化完成后启动看门狗,并在系统关闭或出现异常情况时停止看门狗。
-
系统稳定性和测试:使用看门狗之前,确保系统的稳定性和可靠性。进行全面的系统测试,包括正常操作、异常情况、边界条件等,以确保看门狗能够按预期工作并保护系统免受故障影响。
-
注意看门狗的限制:了解您使用的具体看门狗的限制和特性。不同的单片机和看门狗模块可能具有不同的特性和限制,如最大计数器值、精度、复位时间等。确保在使用中符合相关规范和要求。
-
处理看门狗超时:当看门狗超时发生时,系统将被复位。如果出现看门狗超时复位,请仔细检查系统代码和硬件设计,查找潜在的问题,例如任务优先级、死循环、资源竞争等。
总之,使用看门狗需要确保正确配置和及时刷新,同时进行系统稳定性测试和故障排查,以保证系统的可靠性和稳定性。