???此文档作为对洋桃电子STM32F407单片机视频的整理,B站链接:
????????看门狗功能监控程序是否正常运行,提高系统稳定性。STM32F407单片机内置一个独立看门狗(IWDG)和一个窗口看门狗(WWDG),他们都起到监控作用。
????????看门狗的工作原理是在CubeMX中设置看门狗定时值,单片机运行时看门狗不断倒计数,当倒计数到0时发出复位信号使单片机复位,一旦启动看门狗每隔一段时间《倒计时的时间》单片机就会复位从头运行。为了让程序正常运行要在程序中加入一行重新设置看门狗定时值的程序,这样在定时值减到0之前重置初始值使看门狗重新倒计时不触发复位。如果程序出错或卡死没能在倒计时到0之前重置初始值看门狗则让单片机复位,让出错或卡死的程序重新运行重置初始值的过程称为“喂狗”。看门狗的工作就是监控程序是否正常,程序不断喂狗证明工作正常,程序没有喂狗说明出现问题。但是看门狗不能检测单片机到底出了什么问题,他只能让单片机复位重新运行,类似于电脑死机或蓝屏只要重启就能解决。在看门狗的基本原理之上,又分为独立看门狗和窗口看门狗。
????????看门狗功能实际上是一个定时器,独立看门狗基于一个12位的递减计数器和一个8位的预分频器,它由32KHz内部RC震荡器为其提供时钟,独立看门狗就是指具有独立时钟的看门狗,系统出现问题时独立看门狗可独立工作。图左边是独立看门狗的部分,右边是整体单片机系统。单片机系统由HSE或HSI提供时钟而独立看门狗由LSI独立提供32KHz时钟,时钟源进入看门狗后会有一个8位预分频器进行分频,分频后的时钟驱动一个12位递减计数器,用户可以预先设置计数值,计数值按分频器的频率逐步递减,当数值减到0时触发复位,在复位前若程序重置初始值 (喂狗) 则重新计数,只要单片机正常工作计数器递减到0之前喂狗就不会触发复位,如果出现问题比如外部时钟源断开或程序卡死不能喂狗则触发复位,独立看门狗的特性是在计数器递减到0之前随时可以喂狗。
????????图中纵向表示计数值横向表示时间,斜线表示计数值随着时间不断递减,12位计数器最大值是0xFFF,计数初始值可以设置为0xFFF到0x001之间,从计数开始到触发复位这段时间都可以喂狗。
????????窗口看门狗内置一个7位的递减计数器和一个预分频器,看门狗的时钟和系统共用使用系统主时钟源,使用系统主时钟源,也就是说窗口看门狗没有独立时钟源,而是和ARM内核共用主时钟,窗口看门狗有早期预警中断功能。
????????独立看门狗和窗口看门狗在特性和应用上有所不同,窗口看门狗既能触发复位又能触发中断,窗口看门狗的应用是监控单片机运行时效,必须在规定时间范围内喂狗以判断单片机运行是否精确。独立看门狗仅为了防止程序出错,窗口看门狗不仅要保证程序正常还保证运行精确,如果程序在时间上早执行或晚执行都被认为失去时效性,主要用于对时间要求苛刻的项目。
????????图中纵线表示计数值横线表示时间,斜线表示计数值随时间递减。窗口看门狗的7位计数器最大值为0x7F最小值为0x41,计数值低于0x40时就会产生中断信号,当计数值减到0x3F时会产生复位信号。所以设置的计数器初始值不能小于0x40,另外还要设置“上窗口边界”,上窗口边界值不能超过计数初始值,只能设在初始值到0x40之间。假设把计数初始值设置为0x7F,把上窗口边界设置为0x50,在计数值递减到上窗口边界前不允许喂狗,如果喂狗会判断为“喂狗时间早到”而触发复位,喂狗时间必须在上窗口边界(0x50)到固定的下窗口边界 (0x3F) 之间,这是窗口期。只有在窗口期内喂狗,计数值才会重置初始值,如果计数值到达0x3F时还没有喂狗会判断为“喂狗时间迟到”则触发复位。窗口看门狗还有一个功能是在下窗口边界0x3F之前产生中断信号,计数值到0x40时系统不会复位而会产生看门狗中断,进入看门狗中断处理函数,函数中可完成一些复位前的收尾工作,比如保存数据、标记状态等。处理好后等待计数器到达0x3F触发复位,看门狗中断是给用户做复位前的准备工作。
????????为什么独立看门狗不设置提前中断呢?这是因为如果独立看门狗产生复位表示程序已经错误或卡死不能正常收尾工作,设置中断没有意义。窗口看门狗的复位表示程序能正常运行只是时效性不足,设置中断处理函数是有意义的。
????????独立看门狗的参数设置和开启都可在CubeMX中完成,在程序代码中只需要调用HAL库函数完成喂狗操作,在CubeMX时钟树视图中有IWDG独立看门狗部分,它是由LSI提供32kHz时钟源不可更改,LSI在单片机内核之外独立工作,所以IWDG也可独立工作不受时钟和电源的干扰。
????????预分频系数和计数初始值共同构成看门狗定时器的复位时间。下图是独立看门狗定时时间公式。
????????例如将分频系数设置为64,计数初始值设置为500,时钟频率固定是32kHz,最终定时时间是1秒。如此设置后单片机只要在1秒内进行一次喂狗操作,就能保证单片机不复位,可以按实际的项目要求来选择不同的参数组合达到不同的定时时间。
????????在main.c文件的第46行自动生成了独立看门狗的句柄,第97行自动生成了独立看门狗初始化函数,在单片机上电运行时独立看门狗将开始工作,如果1秒内没有执行一次喂狗操作单片机将复位。
????????在主循环程序的第106行调用HAL_IWDG_Refresh函数,在参数中写入独立看门狗的句柄,当程序执行到此处完成一次喂狗,看门狗定时器再次回到初始定时间,1秒后将复位,只要主循环在1秒内再次执行一次喂狗函数,就可以再次回到初始定时时间保证单片机不会复位。
????????为了验证看门狗是否有效在主循环程序之前的第99行添加了只有复位才会向串口发送“单片机复位”的程序,当超级终端显示此文字表示单片机复位了。在主循环的第106行是HAL库中的喂狗函数,第107行是向串口发送“喂狗”的程序,第108行添加一个延时函数,因为延时的过程中不会执行喂狗函数,所以当我们设置延时时间小于1秒时(测试用800毫秒)单片机不会复位。
????????程序运行的效果是单片机只在上电时复位一次,当修改延时时间大于1秒(测试用1200毫秒)独立看门狗得不到喂狗操作会复位单片机,由于喂狗超时导致反复复位。在实际的项目开发中会使用更长的看门狗定时时间,让主循环程序有足够的时间完成喂狗操作,同时也要合理编写延时和按键处理程序防止出现长时间的中断处理。
????????CubeMX时钟树视图中没有标出WWDG窗口看门狗的时钟部分,这是因为窗口看门狗挂接在APB1总线上,设定的APB1外设时钟就是窗口看门狗的时钟,当前APB1外设时钟频率是36MHZ,计算窗口看门狗定时时间就使用这个频率值。
????????上窗口超时时间和下窗口超时时间需要计算,用于决定执行喂狗的窗口期,例如上窗口时间将分频系数设置为8,计数初始值设置为0x7F窗口值为0x50,时钟固定是36MHZ,最终定时时间是42780微秒,下窗口时间是57344微秒。我们的喂狗时间应该在42.8~57.3毫秒之间有大约15毫秒的窗口时间。
????????在main.c文件第48行自动生成了窗口看门狗的句柄,第97行自动生成和调用了窗口看门狗的初始化函数,执行此行后窗口看门狗开始工作,接下来必须在窗口时间内进行一次喂狗操作。
????????在主循环程序的第107行调用HAL_WWDG_Refresh函数 ,在参数中写入窗口看门狗的句柄,当程序执行到此处完成一次喂狗,但由于窗口看门狗的喂狗操作必须在窗口时间内进行,窗口时间是42.8~57.3毫秒之间,所以第106行添加的延时时间是50毫秒。
????????设置延时时间为50微妙时会在超级终端上看到不断刷新显示“喂狗”,表示在窗口时间内喂狗成功。将延时值修改为42.8~57.3毫秒之外 (例如80毫秒)在超级终端上会不断刷新显示“单片机复位” 表示喂狗操作失败,单片机被窗口看门狗不断复位。在实际的项自开发中如果使用窗口看门狗功能则需要综合考虑喂狗时间,让主循环有足够时间完成喂狗操作,同时也要合理编写延时、按键处理程序,防止出现长时间的中断处理。
??????