目录
概述
由独立的RC振荡器提供时钟(可以在待机和停止模式下运行)
以下条件会触发重置
–当递减计数器(downcounter)的值小于0x000时,复位(如果激活了看门狗)
–如果在窗口外重新加载递减计数器(downcounter),则重置(如果激活了看门狗)
框图
寄存器接口位于VDD电压域中。 看门狗功能位于VDD电压域中,在停止和待机模式下仍然起作用。
通过将值0x0000 CCCC写入IWDG密钥寄存器(IWDG_KR)来启动独立看门狗时,计数器将从复位值0xFFF开始递减计数。
当它到达计数值(0x000)的末尾时,将产生一个复位信号(IWDG复位)。
每当将密钥值0x0000 AAAA写入IWDG密钥寄存器(IWDG_KR)时,都会将IWDG_RLR值重新装入计数器,并防止看门狗复位。
一旦运行,IWDG无法停止。
类窗口看门狗用法
通过在IWDG窗口寄存器(IWDG_WINR)中设置适当的窗口,IWDG也可以用作窗口看门狗。如果在计数器大于IWDG窗口寄存器(IWDG_WINR)中存储的值的同时执行重载操作,则将提供复位。IWDG窗口寄存器(IWDG_WINR)的默认值为0x0000 0FFF,因此如果不更新,则禁用窗口选项。窗口值一改变,就执行一次重装操作,以便将递减计数器重置为IWDG重装寄存器(IWDG_RLR)的值,并简化周期数计算以生成下一 个重装。
启用窗口选项时配置IWDG
1.通过在IWDG密钥寄存器(IWDG_KR)中写入0x0000 CCCC来启用IWDG
2.通过在IWDG密钥寄存器(IWDG_KR)中写入0x0000 5555来启用寄存器访问
3.通过将IWDG预分频器寄存器(IWDG_PR)写入0~7,用来设置IWDG预分频器
4.写入IWDG重载寄存器(IWDG_RLR)
5.等待寄存器更新(IWDG_SR = 0x0000 0000)
6.写入IWDG窗口寄存器(IWDG_WINR),这将自动刷新IWDG重载寄存器(IWDG_RLR)中的计数器值
当IWDG状态寄存器(IWDG_SR)设置为0x0000 0000时,写入窗口值允许RLR刷新计数器值。
禁用窗口选项时配置IWDG
当不使用窗口选项时,可以如下配置IWDG:
1.通过在IWDG密钥寄存器(IWDG_KR)中写入0x0000 CCCC来启用IWDG
2.通过在IWDG密钥寄存器(IWDG_KR)中写入0x0000 5555来启用寄存器访问
3.通过将IWDG预分频器寄存器(IWDG_PR)写入0~7,用来设置IWDG预分频器
4.写入IWDG重载寄存器(IWDG_RLR)
5.等待寄存器更新(IWDG_SR = 0x0000 0000)
6.用IWDG_RLR(IWDG_KR = 0x0000 AAAA)刷新计数器值
启用/禁用窗口选项
•要启用窗口选项,请将窗口值写入IWDG_WINR寄存器。
•否则,通过在密钥寄存器中写入0x0000_AAAA刷新计数器以禁用窗口选项。
如果通过设备选项位启用了“硬件看门狗”功能,则看门狗将在上电时自动启用,并且会产生复位,除非在计数器达到计数结束之前由
写入IWDG密钥寄存器(IWDG_KR),或者如果在窗口内重新加载了下行计数器。
寄存器访问保护
对IWDG预分频器寄存器(IWDG_PR),IWDG重载寄存器(IWDG_RLR)和IWDG窗口寄存器(IWDG_WINR)的写访问受到保护。 要修改它们,用户必须首先在IWDG密钥寄存器(IWDG_KR)中编写代码0x0000 5555。 使用不同的值对该寄存器进行写访问将破坏序列,并且将再次保护寄存器访问。这就是重载操作的情况(写0x0000 AAAA)。
状态寄存器可用于指示预分频器或递减计数器重载值或窗口值的更新正在进行中。当设备进入调试模式(内核暂停)时,IWDG计数器将继续正常工作或停止,具体取决于DBGMCU冻结寄存器中相应位的配置。
寄存器地址
IWDG_KR(密钥寄存器)
偏移地址:0x00
复位值:0x0000 0000
KEY[15:0]:只写,读全为0;写入0xAAAA,刷新IWDG_RLR的值防止复位;写入0x5555允许访问IWDG_PR、IWDG_RLR、IWDG_WINR寄存器;写入0xCCCC将启动看门狗(除非选择了硬件看门狗)
IWDG_PR(预分频寄存器)
偏移地址:0x04
复位值:0x0000 0000
PR[2:0]:可读写,预分频器,为了能够更改预分频器分频器,IWDG状态寄存器(IWDG_SR)的PVU位为复位状态;仅当IWDG状态寄存器(IWDG_SR)中的PVU位为复位值时,从该寄存器读取的值才有效。
000: /4
001: /8
010: /16
011: /32
100: /64
101: /128
110: /256
111: /256
IWDG_RLR(重载寄存器)
偏移地址:0x08
复位值:0x0000 0FFF
RL[11:0]:可读写,仅当IWDG状态寄存器(IWDG_SR)中的RVU位为复位值时,从该寄存器读取的值才有效。
IWDG_SR(状态寄存器)
偏移地址:0x0C
复位值:0x0000 0000
BIT0:PVU。预分频值更新。该位由硬件置1,以指示正在进行预分频器值的更新(最多需要五个LSI周期),它会由硬件复位。仅当PVU位复位后,预分频器的值才能更新。
BIT1:RVU。计数器重装值更新。该位由硬件置1,以指示重装值的更新正在进行中(最多需要五个LSI周期)。仅当RVU位复位后,才能更新重载值。
BIT2:WVU。计数器窗口值更新。该位由硬件置1,以指示正在进行窗口值的更新(最多需要五个LSI周期)。仅当WVU位复位后,才能更新窗口值。仅当通用“窗口”= 1时才生成此位。
IWDG_WINR(窗口寄存器)
偏移地址:0x10
复位值:0x0000 0FFF
WIN[11:0]:可读写,为防止复位,当递减计数器的值小于窗口寄存器值且大于0x0时,必须重新装入递减计数器。IWDG状态寄存器(IWDG_SR)中的WVU位为复位后,才能更改重载值。
仅当IWDG状态寄存器(IWDG_SR)中的WVU位复位后,从该寄存器读取的数据才有效。
时间计算
超时值:从125微秒到32秒。IWDG使用LSI时钟,32 kHz5%精度。
1、确定时钟分频系数:4、8、16、32、64、、256,有时为了计数方便我们除以32,32kHZ/32=1000Hz,即一秒钟1000下。
2、确定向下重载计数值:0~4095.
3、超时时间
IWDG实验
- 新建芯片工程,开启SWD调试接口、使用HSE
- PA0引脚设置GPIO_EXTI0,GPIO mode为:"External Interrupt Mode with Rising edge trigger detection",GPIO设为Pull-down
- 在NVIC中,勾选EXTI0外部中断使能,优先级2
- USART1,mode选择"Asynchronous",Baud Rate:115200,8bits,None,1
- IWDG,勾上"Activated"使能看门狗,时钟分频系统32,向下重载计数值(down-counter reload value)4095,其他默认值
超时时间t=4095*32/32000=4.095s
- 配置时钟树
- 生成代码,打开工程。
- 先修改USART1这部分的代码,在usart.c文件中粘贴如下代码,用于重定向printf输出。同时在main.c文件中加入#include <stdio.h>
#include <stdio.h>
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
- PA0,中断代码,在mian.c文件中写入如下函数
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
UNUSED(GPIO_Pin);
HAL_Delay(10);
if(GPIO_Pin==GPIO_PIN_0 && HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_SET)
{
HAL_IWDG_Refresh(&hiwdg); //刷新计时值,相当于喂看门狗
printf("Refresh iwdg.");
}
}
- main.c文件写入如下代码
#include <stdio.h>
/*
.
*/
int main(void)
{
//加入以下代码
/* USER CODE BEGIN 2 */
__HAL_IWDG_START(&hiwdg);
printf("Initialized watchdog.");
/* USER CODE END 2 */
//*
}
- Debug选项中,勾上"Reset and Run",编译代码,烧录在开发板中,我们要在4.095秒内按下按钮喂狗,不然就会重启芯片。
IWDG窗口寄存器
通过设置这个寄存器,让IWDG也有类似窗口看门狗的功能,当递减计数器的值小于窗口寄存器值且大于0x0时才能更新IWDG_RLR的值,在范围之外更新计数器引起芯片重启。
- 保持前面工程设置不变,修改window value的值为3095,意思是1秒之后,3.095秒之内喂狗就不会引起重启
- 生成代码。编译烧录芯片就可
- 如果想在代码中修改window的值,可以改写mian.c文件中的函数
IWDG_HandleTypeDef hiiwdg;
void Change_Window(void)
{
hiiwdg.Instance = IWDG;
hiiwdg.Init.Prescaler = IWDG_PRESCALER_32;
hiiwdg.Init.Window = 1095; //修改窗口值
hiiwdg.Init.Reload = 4095;
if (HAL_IWDG_Init(&hiiwdg) != HAL_OK)
{
Error_Handler();
}
}