打印
[STM32H5]

【STM32 Nucleo-64测评】3 使用GPIO外部中断测试独立看门狗

[复制链接]
1201|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
NUC, IO, GPIO, STM, ST, ADC, AD
本帖最后由 尹小舟 于 2024-8-9 20:46 编辑

STM32H5独立看门狗 介绍
    独立看门狗(Independent Watchdog, IWDG)是微控制器(MCU)中一种重要的安全机制,用于监控系统的运行状态,   防止程序因意外情况(如死循环、程序跑飞等)而陷入无限执行状态,  从而无法响应外部事件或进行必要的系统重启。
    IWDG 本质上是一个定时器,但其设计目的和功能与普通的定时器有所不同。
    该定时器是一个 12 位的递减计数器,
计数器从预设的初始值开始递减,直到减到0。这个初始值通常可以配置,以决定看门狗的超时时间。
    在计数器值减到0之前,通过软件或硬件的方式重置计数器的值,这个操作被称为“喂狗”。喂狗操作可以阻止复位信号的产生,并允许系统继续运行。
    当计数器的值减到0时,如果此时没有通过“喂狗”操作重置计数器,则看门狗会输出一个复位信号,使系统复位。这是看门狗防止系统死锁的主要手段。或产生一个中断信号,进入看门狗中断。
    看门狗功能由VDD电压域供电,即使在其他一些系统模块(如CPU)进入低功耗模式(如停止模式或待机模式)时,看门狗仍然可以正常工作,持续监控系统状态


使用场景:
  • 防止软件死循环:如果程序因某种原因陷入死循环,看门狗可以在一定时间后复位系统,从而避免系统长时间无法响应。
  • 硬件故障检测:在某些情况下,看门狗也可以用于检测硬件故障,如时钟源故障,导致系统无法正常运行。
  • 系统监控:在需要高可靠性的系统中,看门狗可以作为系统健康状态的一个监控指标。

注意事项:
  • 合理设置超时时间:超时时间设置过短可能导致系统频繁复位,影响正常操作;设置过长则可能无法及时响应系统异常。
  • 确保喂狗操作:在系统正常运行时,必须确保在计数器减到0之前进行喂狗操作,以避免不必要的系统复位。
  • 考虑低功耗影响:在低功耗模式下,需要特别注意看门狗的工作状态及其对系统功耗的影响。
IWDG框图



API介绍

IWDG 句柄

typedef struct
{
IWDG_TypeDef *Instance; /* IWDG 寄存器基地址 */
IWDG_InitTypeDef Init; /* IWDG 初始化参数 */
}IWDG_HandleTypeDef;
1Instance:指向 IWDG 寄存器基地址。
2InitIWDG 初始化结构体,用于配置计数器的相关参数。


IWDG_InitTypeDef 结构体
typedef struct
{
uint32_t Prescaler; /* 预分频系数 */
uint32_t Reload; /* 重装载值 */
uint32_t Window; /* 窗口值 */
uint32_t EWI; /* IWDG 早期唤醒中是否唤醒以及比较器的值,设置为 0 表示关闭 EWI */
} IWDG_InitTypeDef;
1Prescaler:预分频系数,IWDG_PRESCALER_4 IWDG_PRESCALER_256
2Reload:重装载值,范围:0 0x0FFF
3Window:窗口值。
4EWI:比较器的值。

HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
初始化独立看门狗,用于把重装载寄存器的值重载到计数器中,防止 IWDG 复位。


HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
喂狗函数


程序代码

外部中断初始化

BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
独立看门狗初始化
static void MX_IWDG_Init(void)
{
  /* USER CODE END IWDG_Init 1 */
  hiwdg.Instance = IWDG;
  hiwdg.Init.Prescaler = IWDG_PRESCALER_32;
  hiwdg.Init.Window = IWDG_WINDOW_DISABLE;
  hiwdg.Init.Reload = 500;
  hiwdg.Init.EWI = 0;
  if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
  {
    Error_Handler();
  }
}

main函数
/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ICACHE_Init();
        MX_IWDG_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Initialize leds */
  BSP_LED_Init(LED_GREEN);

  /* Initialize USER push-button, will be used to trigger an interrupt each time it's pressed.*/
  BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);

  /* Initialize COM1 port (115200, 8 bits (7-bit data + 1 stop bit), no parity */
  BspCOMInit.BaudRate   = 115200;
  BspCOMInit.WordLength = COM_WORDLENGTH_8B;
  BspCOMInit.StopBits   = COM_STOPBITS_1;
  BspCOMInit.Parity     = COM_PARITY_NONE;
  BspCOMInit.HwFlowCtl  = COM_HWCONTROL_NONE;
  if (BSP_COM_Init(COM1, &BspCOMInit) != BSP_ERROR_NONE)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN BSP */

  /* -- Sample board code to send message over COM1 port ---- */
  printf("Welcome to STM32 world !\n");

  /* Switch on leds */
  BSP_LED_On(LED_GREEN);
       
        led_gpio_init();
  sw_gpio_init();
  /* USER CODE END BSP */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* -- Sample board code for User push-button in interrupt mode ---- */
    if (BspButtonState == BUTTON_PRESSED)
    {
      /* Update button state */
      BspButtonState = BUTTON_RELEASED;
      /* -- Sample board code to toggle leds ---- */
      BSP_LED_Toggle(LED_GREEN);
                        if(HAL_IWDG_Refresh(&hiwdg) != HAL_OK)
                        {
                                /* Refresh Error */
                                Error_Handler();
                        }
      /* ..... Perform your action ..... */

    }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}


实验现象
不按按键触发中断的话就会复位打印

















使用特权

评论回复
沙发
亚瑟| | 2024-8-14 09:48 | 只看该作者
能不能用定时器代替看门狗啊?

使用特权

评论回复
板凳
Undshing| | 2024-8-14 09:54 | 只看该作者
亚瑟 发表于 2024-8-14 09:48
能不能用定时器代替看门狗啊?

软件卡死了定时器也不能正常工作了吧

使用特权

评论回复
地板
尹小舟|  楼主 | 2024-8-14 14:53 | 只看该作者
亚瑟 发表于 2024-8-14 09:48
能不能用定时器代替看门狗啊?

不能哦,开门狗有独特的设计

使用特权

评论回复
5
狄克爱老虎油| | 2024-8-17 23:43 | 只看该作者
有专门的看门狗芯片吧

使用特权

评论回复
6
grfqq325| | 2024-8-28 12:03 | 只看该作者
如果程序因某种原因陷入死循环,IWDG可以在超时时自动复位系统,从而避免系统长时间无法响应。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

86

帖子

2

粉丝