stm32F407下IWDG
概念
- STM32F4 的独立看门狗由内部专门的 32Khz 低速时钟(LSI)驱动
- 预分频器(prescaler):设置看门狗时钟的分频系数,该寄存器是占用3位,即最大值位为256
- 重载计数器(reload value):向下计数
配置
时钟配置
独立看门狗时钟挂在LSI时钟上,stm32F407的内部时钟是32khz,因此看门狗的时钟也是32khz,通过IDE的时钟图可以看到时钟配置和频率数因此这里无需设置
IWDG配置
配置一个周期为1秒的看门狗,计算方式为:
32000hz/(32*1000)=1hz,即周期为1秒,即为1秒为溢出时间
- 启用IWDG:System core-->IWDG-->Activated
- prescaler:32
- reload:1000
实现
没有喂狗
由于看门狗设置的监听周期是1秒,在1秒周期内如果没有喂狗,看门狗将重置系统:
在while中,每隔300ms向串口输出一次信息,由于1秒看门狗将重置系统,理论上只能输出3次信息将重新打印
代码
while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(cnt==0) { printf("Sys reset\r\n"); } printf("cnt=%d\r\n",cnt); cnt++; HAL_Delay(300); }
- 输出结果
我们可以看到串口输出的信息,cnt输出的最大值为3,然后系统重置,进行循环输出。
这就意味着看门狗起作用了,没有喂狗导致系统重置
Sys reset
cnt=0
cnt=1
cnt=2
cnt=3
Sys reset
cnt=0
cnt=1
cnt=2
cnt=3
启用喂狗
喂狗的函数为:HAL_IWDG_Refresh,在看门狗的设置周期内,调用喂狗函数,将重置装载器(reload),这样就不会触发看门狗,导致系统重置
代码
while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(cnt==0) { printf("Sys reset\r\n"); } printf("cnt=%d\r\n",cnt); cnt++; HAL_Delay(300); HAL_IWDG_Refresh(&hiwdg); }
- 输出结果
Sys reset cnt=0 cnt=1 cnt=2 cnt=3 cnt=4 cnt=5 cnt=6 cnt=7 cnt=8 cnt=9 cnt=10 cnt=11 cnt=12 cnt=13 cnt=14 cnt=15 cnt=16 cnt=17 cnt=18 cnt=19 cnt=20 cnt=21 cnt=22 cnt=23 cnt=24 cnt=25 cnt=26 cnt=27 cnt=28
其他问题
- 调用喂狗函数后,系统输出的最大值为256,不知道原因在哪。(我猜是云分频计数器最大值是256吧)
- 预分频寄存器只占用3个bit,计算方式为:42的n次方,如寄存器位001(1),预分频系数位:42=8;如寄存器位110(6),4*2的6次方=256;在实际中,预分频系数是直接设置的,无需根据位来计算;
- 重载数值寄存器占用12位,因此reload的最大值是4095.