完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
【嵌入式系统】独立看门狗原理+看门狗实验分析
1、看门狗模块概述 在由单片机构成的微机系统中,由于单片机工作常常会受到来自外界电磁场干扰导致程序跑飞,陷入死循环——即程序正常运行被打断,系统无法继续工作。这种情况下会造成系统陷入停滞状态,发生不可预料的后果。因此出于对单片机运行状态进行实时监测的考虑,产生了一种专门用于监测单片机程序运行状态的模块或芯片,称为看门狗。STM32F10xxx内置两个看门狗:独立看门狗(IWDG, Independent WatchDoG)和窗口看门狗(WWDG, Windows WatchDoG),提供了更高的安全性、时间的精确性和使用的灵活性。 图1 STM32基本看门狗类型 WWDG和IWDG原理有所区别,本篇文章仅对IWDG作分析 2、IWDG原理 图2 IWDG结构框图 IWDG由独立时钟LSI驱动且处于VDD供电区,因此可在睡眠、停机、待机模式下运行。当IWDG_KR写入0xCCCC时IWDG递减计数器启动,从0xFFFF开始减计数,当计数器计数为0时系统就进行复位。在正常工作状态下,每隔一段时间会向IWDG_KR写入0xAAAA,即将一个寄存在IWDG_RLR的12bits数值装载到IWDG计数器中——可见正常工作下IWDG永远不会触发系统复位;当系统跑飞时将无法正常喂狗,从而一段时间后产生系统复位,维护系统运行稳定。 看门狗溢出时间如下,当计数器第一次重装载后,超过 T o u t T_{out} Tout不重装载将产生系统复位。在战舰版中,LSI如图2为40kHz,因此令 f L S I f_{LSI} fLSI=40即可 T o u t = ( 4 × 2 P r e ) × R L R f L S I T_{out}=frac{(4×2^{Pre})×RLR}{f_{LSI}} Tout=fLSI(4×2Pre)×RLR 图3 IWDG主要寄存器 3、IWDG实验分析 本实验基于STM32NANO(HAL库),结合KEY、LED与IWDG观察看门狗的监视复位功能。 int main(void) { HAL_Init(); //初始化HAL库 Stm32_Clock_Init(RCC_PLL_MUL9); //设置时钟,72M delay_init(72); //初始化延时函数 uart_init(115200); //初始化串口 LED_Init(); //初始化LED KEY_Init(); //初始化按键 delay_ms(100); //延时100ms再初始化看门狗 IWDG_Init(IWDG_PRESCALER_64,625); //分频数为64,重载值为625 LED0=0; while(1) { if(KEY_Scan(1)==WKUP_PRES) //如果WK_UP按下,喂狗 { IWDG_Feed(); //喂狗 } delay_ms(10); } } IWDG_Init(IWDG_PRESCALER_64,625)设置了溢出时间为: T o u t = 64 × 625 40 m s = 1 s T_{out}=frac{64×625}{40}ms=1s Tout=4064×625ms=1s 即超过1s没有喂狗,系统将执行复位。 LED0=0使用位带操作进行点灯,位带操作点灯的原理可以参考:位带操作原理+LED实验分析while(1)循环内将喂狗函数和WK_UP按键绑定,即按下WK_UP就执行了重装载操作(KEY_Scan(1)即选用支持连按)。IWDG初始化前的延时delay_ms(100)是为了使LED0的闪烁可见:如图4所示,若没有delay(),两次点灯时间间隔很短,无法观察到因为复位导致的LED0灭灯现象。 图4 下面讲解封装过的独立看门狗初始化函数void IWDG_Init(u8,u16)原理: IWDG_HandleTypeDef IWDG_Handler; //独立看门狗句柄 void IWDG_Init(u8 prer,u16 rlr) { IWDG_Handler.Instance=IWDG; IWDG_Handler.Init.Prescaler=prer; //设置IWDG分频系数 IWDG_Handler.Init.Reload=rlr; //重装载值 HAL_IWDG_Init(&IWDG_Handler); //初始化IWDG,默认会开启独立看门狗 HAL_IWDG_Start(&IWDG_Handler); //启动独立看门狗 } 首先在IWDG头文件中定义了全局的IWDG句柄,句柄定义如下,包含的是IWDG寄存器组基址以及预分频系数、重装载值等资源信息。 typedef struct { IWDG_TypeDef *Instance; /*!《 Register base address */ IWDG_InitTypeDef Init; /*!《 IWDG required parameters */ }IWDG_HandleTypeDef; 接下来在函数中对这个全局句柄进行初始化,将输入参数Prep、Rlr以及IWDG基址赋给IWDG_Handle,之后使用此句柄进行实质性的IWDG初始化和启动。下面给出了IWDG的初始化封装HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *)中 与IWDG配置有关的代码 HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg) { …… /* Enable IWDG. LSI is turned on automaticaly */ __HAL_IWDG_START(hiwdg); /* Enable write access to IWDG_PR and IWDG_RLR registers by writing 0x5555 in KR */ IWDG_ENABLE_WRITE_ACCESS(hiwdg); /* Write to IWDG registers the Prescaler & Reload values to work with */ hiwdg-》Instance-》PR = hiwdg-》Init.Prescaler; hiwdg-》Instance-》RLR = hiwdg-》Init.Reload; /* Reload IWDG counter with value defined in the reload register */ __HAL_IWDG_RELOAD_COUNTER(hiwdg); /* Return function status */ return HAL_OK; } 大多数配置都是通过宏定义函数进行的,例如 #define WRITE_REG(REG, VAL) ((REG) = (VAL)) #define IWDG_ENABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)-》Instance-》KR, IWDG_KEY_WRITE_ACCESS_ENABLE) 其中IWDG_KEY_WRITE_ACCESS_ENABLE就是0x5555,即往KR写入0x5555,参照图3知此时取消了RLR与PR的写保护,可以向其中写入预分频因子和重装载值了。 将IWDG初始化并启动后,若不进行喂狗系统将在溢出时间到达后自动复位。IWDG_Feed()是对宏定义函数__HAL_IWDG_RELOAD_COUNTER(hiwdg)的封装,即往KR中写入0xAAAA对计数器进行重装载。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1777 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1080 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1678 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
731浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
595浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
554浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 07:01 , Processed in 0.841160 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号