江科大独立/窗口看门狗hal库实现
独立看门狗hal库相关函数
初始化结构体
typedef struct
{uint32_t Prescaler; /*分频值*/uint32_t Reload; /*自动重装值*/} IWDG_InitTypeDef;
句柄
typedef struct
{IWDG_TypeDef *Instance; /*!寄存器基地址 */IWDG_InitTypeDef Init; /*初始化结构体*/
} IWDG_HandleTypeDef;
启动IWDG看门狗
#define __HAL_IWDG_START(__HANDLE__)
设置自动重装值
#define __HAL_IWDG_RELOAD_COUNTER(__HANDLE__)
初始化函数,喂狗函数
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg);
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg);
独立看门狗
按照江科大的配置来,独立看门狗,分频为16分频,自动重装值为2499,也就是
40000Hz/16/2500 = 1s
IWDG独立看门狗使用的是LSI低速内部时钟40Khz
1s内得进行喂狗,不然就会重置程序
__HAL_RCC_CLEAR_RESET_FLAGS()
清除复位标志位相关宏定义,这个在rcc文件里面
我们在初始化完成独立看门狗后,硬件自动启动了IWDG_Start,启动看门狗,启动了就不能再关闭了,且我们初始化完成后得立马进行一次喂狗,而且得在初始化代码后面紧跟着,否则可能因为别的代码干扰了喂狗时间,导致喂狗失败重启。
对于标志位的判断,这里我使用的是!=RESET去判断是不是独立看门狗导致的复位重启,==SET在我这不会判断成功,判断不了独立看门狗导致的复位。可能是硬件的问题
int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_IWDG_Init();HAL_IWDG_Refresh(&hiwdg);//初始化完成后立刻执行一次喂狗,且在初始化代码后面最好,否则可能会因为别的代码导致判别错误OLED_Init();OLED_ShowString(1, 1, "IWDG TEST");/*判断复位信号来源*/if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET) //如果是独立看门狗复位{OLED_ShowString(2, 1, "IWDGRST"); //OLED闪烁IWDGRST字符串HAL_Delay(500);OLED_ShowString(2, 1, " ");HAL_Delay(100);__HAL_RCC_CLEAR_RESET_FLAGS(); //清除标志位}else //否则,即为其他复位{OLED_ShowString(3, 1, "RST"); //OLED闪烁RST字符串HAL_Delay(500);OLED_ShowString(3, 1, " ");HAL_Delay(100);}while (1){Key_GetNum(); //调用阻塞式的按键扫描函数,模拟主循环卡死/* USER CODE END WHILE */HAL_IWDG_Refresh(&hiwdg); //重装计数器,喂狗OLED_ShowString(4, 1, "FEED"); //OLED闪烁FEED字符串HAL_Delay(200); //喂狗间隔为200+600=800msOLED_ShowString(4, 1, " ");HAL_Delay(600);}
}
窗口看门狗相关函数
typedef struct
{uint32_t Prescaler; /*分频值*/uint32_t Window; /*上窗口值*/uint32_t Counter; /*下窗口计数值*/uint32_t EWIMode ; /*提前喂狗中断*/} WWDG_InitTypeDef;
初始化函数
HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg);
void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg);
喂狗函数
HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg);
窗口看门狗
按照江科大的配置,分频值为8,时间分别是30,50ms;
下窗口值通过公式计算为85
上窗口值计算为118
这部分和独立看门狗一样的,喂狗晚了,或者早了都会进行窗口看门狗复位,可以在main主函数里面自行修改延时时间来观察现象。
int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();OLED_Init();/*显示静态字符串*/OLED_ShowString(1, 1, "WWDG TEST");/*判断复位信号来源*/if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET) //如果是窗口看门狗复位{OLED_ShowString(2, 1, "WWDGRST"); //OLED闪烁WWDGRST字符串HAL_Delay(500);OLED_ShowString(2, 1, " ");HAL_Delay(100);__HAL_RCC_CLEAR_RESET_FLAGS(); //清除标志位}else //否则,即为其他复位{OLED_ShowString(3, 1, "RST"); //OLED闪烁RST字符串HAL_Delay(500);OLED_ShowString(3, 1, " ");HAL_Delay(100);}MX_WWDG_Init();while (1){/* USER CODE END WHILE */Key_GetNum(); //调用阻塞式的按键扫描函数,模拟主循环卡死OLED_ShowString(4, 1, "FEED"); //OLED闪烁FEED字符串HAL_Delay(20); //喂狗间隔为20+20=40msOLED_ShowString(4, 1, " ");HAL_Delay(20);HAL_WWDG_Refresh(&hwwdg); //重装计数器,喂狗/* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}