本文将介绍 STM32F10X 独立看门狗 IWDG 的基础知识,主要参考STM32F10x参考手册。并且实现一个简单的 IWDG 实验。实验主要效果:没有喂狗时,LED保持闪烁,完成喂狗后,LED 状态保持。
基于STM32CubeMX 实现STM32F10X 独立看门狗 IWDG
第一部分 基础理论
1. IWDG 简介
2. IWDG 主要性能
3. IWDG 功能描述
3.1 硬件看门狗
3.2 寄存器访问保护
4. IWDG 寄存器
4.1 键值寄存器(IWDG_KR)
4.2 预分频寄存器(IWDG_PR)
4.3 重装载寄存器(IWDG_RLR)
4.4 状态寄存器(IWDG_SR)
4.5 IWDG 寄存器映像
5. 溢出时间计算
第二部分 基础实验
1. 软件与硬件
1.1 硬件要求
1.2 软件要求
2. STM32CubeMX配置开发板
3. 程序代码
3.1 usart.c
3.2 main.c
4. 程序分析
4.1 主要功能
4.2 主要函数
(1)STM32F10X内置了独立看门狗 IWDG,其可用来检查和解决由软件错误而引起的故障。当其递减计数器到达给定的超时的值时,产生系统复位。
(2)IWDG 由专用的低速时钟(LSI)驱动,在主时钟发生故障时,其也能保持运行状态。
(3)IWDG 最适用于那些需要看门狗完全独立运行于主程序之外并且对时间准确性要求较低的程序应用中。
(1)独立运行的递减计数器
(2)时钟由独立的RC振荡器提供(可在停止和待机模式下工作)
(3)看门狗被激活后,则在计数器计数至0x000时产生复位
当 Key Register(IWDG_KR) 寄存器写入 0xCCCC 时,独立看门狗将被启动,计数器将从 0xFFF 开始递减,但到达计数器末端 0x000 时将产生复位信号(IWDG RESET),无论何时 IWDG_KR register 写入键值 0xAAAA, IWDG_RLR中的值都会被重新被加载到计数器,从而避免产生看门狗复位。以下为 IWDG 模块的功能框图。
注:看门狗功能处于VDD供电区,即在停机和待机模式时仍能正常工作。
如果通过设备选项位中使能 “Hardware watchdog”功能,在系统上电复位后,看门狗自动开始运行;如果计数器到达计数终点之前,若 Key register 没有由软件向其写入相应的值,则系统将会产生复位。
(1)IWDG_PR 和 IWDG_RLR寄存器具有写保护功能。
(2)要修改这两个寄存器的值,必须先向 IWDG_KR 寄存器中写入0x5555。
(3)将其他值(除0x5555之外)写入这个寄存器将会打乱操作顺序,IWDG_PR和IWDG_RLR 寄存器将重新被保护。
(4)重装载操作(即写入0xAAAA)也会启动写保护功能。
(5)状态寄存器指示预分频值和递减计数器是否正在被更新。
本实验基于STM32CubeMX实现对STM32开发板的配置,实验效果将是开发板上的 LED 将保持闪烁(看门狗时间溢出,系统不断重置),当按键被按下时,看门狗计数器重装载值更新(即所谓的“喂狗”),系统将不会重置,LED 状态保持。当按键被松开时,看门狗计数器不断递减,若重装载值无更新,则系统再次发生重置。
(1)ALIENTEK ELITE STM32F103 开发板 (STM32F103ZET6 芯片)
(2)USB转TTL 模块
(1)Java Runtime Environment (JRE) 1.8.0 版本
(2)STM32CubeMX 5.6.1 版本
(3)IAR Embedded Workbench 8.0
(4)串口调试工具
其他具体配置参考基于STM32CubeMX 实现串口通信控制 LED 和蜂鸣器,无需配置蜂鸣器,但需要开启 IWDG
实现printf的重定向
/* USER CODE BEGIN 0 */
/******************************************************************
*@brief Retargets the C library printf function to the USART.
*@param None
*@retval None
******************************************************************/
#include "stdio.h"
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int _io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__*/
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END 0 */
(1)添加头文件
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include
#include
/* USER CODE END Includes */
(2)宏定义
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define KEY0_PRESS HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4) == GPIO_PIN_RESET
#define KEY1_PRESS HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3) == GPIO_PIN_RESET
/* USER CODE END PD */
(3)程序主体
/* USER CODE BEGIN 2 */
printf("\n\r***** No Feed Dog *****\n\r");
printf("\n\r***** System Reset *****\n\r");
HAL_Delay(100);
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_5);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(KEY1_PRESS || KEY0_PRESS)
{
HAL_IWDG_Refresh(&hiwdg);
printf("\n\r***** Feed Dog *****\n\r");
}
HAL_Delay(10);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
(1)没有喂狗,LED闪烁
(2)完成喂狗,LED状态保持