完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
窗口看门狗WWDG
IWDG与WWDG的异同点 WWDG的中断相较于IWDG的优势 当我们需要在程序跑飞时保存一些珍贵的数据,IWDG真的是无能为力,IWDG的功能就是“当检测到程序跑飞立刻复位单片机,就相当于危险发生时不管你什么重要的数据,保住单片机的命要紧”;与IWDG不同的WWDG是“当检测到程序跑飞时,我们不急着作复位的决定,我们先进入中断服务函数进行一些必要的操作,比如保存数据……等关键操作,然后在紧急复位抢救单片机的生命”。 IWDG与WWDG的检测时钟 IWDG用的是LSI内部低速时钟,LSI本身不是特别的精准而且LSI是外部时钟源,如果单片机的内部时钟源故障或因外部干扰发生紊乱,我们可以采用外部时钟源LSI来对这个单片机来个复位操作,拯救单片机; WWDG用的是APB1内部高速时钟源比较精确,该时钟源是由APB1总线时钟4096分频而来,如果单片机内部时钟源废了,那么WWDG的时钟就失效了,WWDG自己都乱套了,当然顾不了单片机了。 IWDG与WWDG的触发复位条件不同 IWDG的计数方式 WWDG的计数方式 IWDG与WWDG的检测力度不同 WWDG相比于IWDG有更小的“喂狗”时间范围,当我们的程序跑飞了之后,我们也不知道具体那里跑飞了,可能是时钟源跑飞了。当时钟源跑飞了,可能会使得递减计数器的值发生改变但是仍在“喂狗”时间范围之内,此时不足以触发复位。针对于这种情况,我们缩小了“喂狗的时间范围“,这样可以尽可能地减小” 递减计数器的值发生改变但是仍在“喂狗”时间范围之内“发生的可能性。因此,相比于IWDG,WWDG对程序的监控有更强的监测力度。 WWDG的工作原理 我们应该格外关注的是:如何才可以触发复位操作?
CR控制寄存器 注:T6-T0是用来存储喂狗时的计数器值的。 CFR窗口配置寄存器 注:WDGTB是用来设置预分频系数的,W是用来设置窗口阈值上限的,窗口阈值下限的取值范围为[0x7F,0x3F),窗口阈值下限已经被确定了无需人工定义(窗口阈值下限=0x40=64)。 SR状态寄存器 WWDG超时时间计算 注:计数器重装值必须大于窗口阈值上限! WWDG的库函数 WWDG库函数(含中断服务函数)的使用
代码示例 Main.c #include "stm32f10x.h" #include "led.h" #include "wwdg.h" #include "delay.h" #include "key.h" int main() { delay_init(); // 由于delay函数中包含时钟,因此我们要初始化delay函数 delay_ms(500); // 延迟500ms LED_InitConfig(); // LED0初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 中断优先级分组 WWDG_InitConfig(); // WWDG初始化 KEY_InitConfig(); // KEY0初始化 while(1) { if(KEY0 == 0) { WWDG_SetCounter(0x5F); } } } void WWDG_IRQHandler() { if(WWDG_GetFlagStatus() == SET) // 读取中断标志位被设置与否 { LED0 = !LED0; } WWDG_ClearFlag(); // 软件清除WWDG中断标志位 } Led.c #include "led.h" #include "stm32f10x.h" void LED_InitConfig() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能外设时钟 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // 配置GPIO引脚属性 GPIO_SetBits(GPIOB, GPIO_Pin_5); // 初始化GPIO引脚输出电平 } Led.h #ifndef _LED_H #define _LED_H #include "sys.h" void LED_InitConfig(); #define LED0 PBout(5) #endif Key.c #include "key.h" #include "stm32f10x.h" void KEY_InitConfig() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); // 使能KEY0的外设时钟 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE, &GPIO_InitStructure); // 配置GPIO的属性 } Key.h #ifndef _KEY_H #define _KEY_H void KEY_InitConfig(); #define KEY0 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4) #endif Wwdg.c #include "wwdg.h" #include "stm32f10x.h" void WWDG_InitConfig() { NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // 使能WWDG的外设时钟(只要是有内部时钟驱动都得使能外设时钟) WWDG_SetPrescaler(WWDG_Prescaler_8); // 设置分频系数 WWDG_SetWindowValue(0x5F); // 设置窗口阈值上限 WWDG_Enable(0x5F); // 使能WWDG并且设置计数器初值 NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // 配置NVIC嵌入式中断向量优先级 WWDG_EnableIT(); // 使能WWDG中断 } Wwdg.h #ifndef _WWDG_H #define _WWDG_H void WWDG_InitConfig(); #endif 运行结果
|
||
|
||
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2955 浏览 16 评论
3455 浏览 1 评论
8987 浏览 16 评论
4050 浏览 18 评论
1102浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 07:20 , Processed in 1.278768 second(s), Total 81, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号