完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
窗口看门狗基本知识
什么是窗口看门狗 它也是一个看门狗,不过它的刷新(喂狗)操作,要在一个窗口时间内进行,不能大于时间窗的上限值或者小于下限值(0x40),这是它和独立看门狗不一样的地方。 窗口看门狗的作用 监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。(注:这里的故障不是程序死机,而是程序逻辑出现错误,导致没能够在窗口时间内刷新窗口看门狗)。除非递减计数器的值在T6位(WWDG–》CR的第六位)变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。在递减计数器达到窗口配置寄存器(WWDG–》CFR)数值之前,如果7位的递减计数器数值(在控制寄存器中)被刷新,那么也将产生一个MCU复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。如下图所示: 看了上面的好久没看懂 就是 0x40(01000000)固定下窗口和上窗口w【6 :0】(可能在这里又有疑问了 w【6:0】是什么,我的理解是寄存器的0位到6位 一共7位 也就是 0- 127)之间才允许刷新,否则复位 所以要避免复位,递减计数器必须在其值小于窗口寄存器的数值并且大于0x3f时被重新装载,因为窗口看门狗有一个WEI中断,开启时,当递减计数器到达0x40时,则产生此中断,相应的中断服务程序(ISR)可以用来加载计数器以防止WWDG复位 WWDG的寄存器代码 test.c 实验现象,D6灯,亮后熄灭,然后灯闪烁 #include “sys.h”#include “delay.h”#include “usart.h”#include “led.h”#include “key.h”#include “wdg.h”int main(void){ Stm32_Clock_Init(9); uart_init(72,115200); delay_init(72); LED_Init(); KEY_Init(); LED1 = 0; delay_ms(300); WWDG_Init(0x7F,0x5F,3); //WWDG_Init(计数器值,窗口寄存器为5f,分频数为8) //详细看wdg.c LED1 = 0; while(1) { LED1= 1; }} wdg.h #ifndef __WDG_H#define __WDG_H#include “sys.h”void IWDG_Init(u8 prer,u16 rlr);void IWDG_Feed(void);void WWDG_Init(u8 tr,u8 wr,u8 fprer);//窗口初始化void WWDG_Set_Counter(u8 cnt);//重置WWDG计数器的值#endif wdg.c #include “wdg.h”#include “led.h”void IWDG_Init(u8 prer,u16 rlr){ IWDG-》KR = 0x5555; IWDG-》PR = prer; IWDG-》RLR = rlr; IWDG-》KR = 0xAAAA; IWDG-》KR = 0xCCCC;}void IWDG_Feed(void){ IWDG-》KR = 0xAAAA;}//上面的是独立看门狗从这里是窗口看门狗u8 WWDG_CNT = 0x7f;//0x7f 0111 1111 计数器最大值void WWDG_Init(u8 tr,u8 wr,u8 fprer)//初始化窗口看门狗(计数器值,窗口值,分频系数){ RCC-》APB1ENR |= 1《《11; //使能WWDG时钟,(独立有自己的时钟,窗口用的是PCLK1时钟) WWDG_CNT = tr&WWDG_CNT; //初始化计数器 0x7f&0x7f = 0x7f WWDG-》CFR |= fprer《《7; WWDG-》CFR &= 0xFF80; //这两步的作用是:CK计时器时钟(PCLK1/4096)除以8; //窗口看门狗超时公式: // Twwdg(超时时间)=(4096×2^WDGTB(预分频系数)×(T[5:0]+1)) /Fpclk1(时钟频率); WWDG-》CFR |= wr; //设定窗口值 WWDG-》CR |= WWDG_CNT; //设定计数器值 WWDG-》CR |= 1《《7; //开启看门狗 MY_NVIC_Init(2,3,WWDG_IRQn,2); //抢占2,子优先级3,组2 WWDG-》SR = 0x00; //清除提前唤醒标志 WWDG-》CFR |= 1《《9; //使能提前唤醒中断}void WWDG_Set_Counter(u8 cnt)//重设置WWDG计数器{ WWDG-》CR = (cnt&0x7F); //重设置7位计数器}void WWDG_IRQHandler(void)//窗口看门狗中断服务函数{ WWDG_Set_Counter(WWDG_CNT); //重设窗口看门狗的值 WWDG-》SR = 0x00; //清除提前唤醒标志位 LED2 = !LED2;} WWDG的HAL库介绍 WWDG操作HAL库 头文件:stm32f1xx_hal_wwdg.h 源文件:stm32f1xx_hal_wwdg.c 重要函数 WWDG初始化函数 HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg) WWDG启动函数 HAL_StatusTypeDef HAL_WWDG_Start(WWDG_HandleTypeDef *hwwdg)HAL_StatusTypeDef HAL_WWDG_Start_IT(WWDG_HandleTypeDef *hwwdg) WWDG喂狗函数 HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg, uint32_t Counter) WWDG中断处理函数 void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg) WWDG中断处理回调函数 __weak void HAL_WWDG_WakeupCallback(WWDG_HandleTypeDef* hwwdg) 代码 main.c #include “MyIncludes.h”u16 sys_cnt = 0;void systick_isr(void){ if(sys_cnt 《100 ) sys_cnt++; else { sys_cnt = 0; HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_4|GPIO_PIN_5); //反转PC4 PC5 灯 }}void wwdg_isr(void){ if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET ) //按键 PA0 key1 { Wwdg_Feed(); //喂狗,重设窗口看门狗值 }}int main(void){ System_Init(); LED_Init(); Key_Init(); HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4|GPIO_PIN_5,GPIO_PIN_SET); //关闭PC4 PC5 LED灯 delay_ms(1000); HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4|GPIO_PIN_5,GPIO_PIN_RESET); //打开PC4 PC5 LED灯 delay_ms(1000); SysTick_Init(systick_isr); Wwdg_Init(wwdg_isr); while(1) { }}/*窗口看门狗实验现象和独立看门狗差不多,如果不喂狗就会产生系统复位,那么一直进行间隔1000ms PC4 PC5灯亮灭的现象,如果按下key1,也就喂狗,那么就不会产生系统复位则会进行systick滴答定时器PC4 PC5灯的快速闪烁。*/```C**wwdg.h**```cpp#ifndef __WWDG_H_#define __WWDG_H_#include “stm32f1xx.h”#include “stm32_types.h”#include “stm32f1xx_hal.h”typedef struct{ void (*Wwdg_Handle)(void); //函数指针,和Systic.h中的差不多,也是 //最终指向void wwdg_isr(void)}_WWDG_ISR;void Wwdg_Init(void(*ISR)(void));//窗口看门狗初始化函数void Wwdg_Feed(void);//喂狗函数#endif wwdg.c #include “wwdg.h”_WWDG_ISR Wwdg_ISR;WWDG_HandleTypeDef WwdgHandle;//结构体变量声明void Wwdg_Init(void(*ISR)(void)){ Wwdg_ISR.Wwdg_Handle = ISR; //函数指针指向ISR if(__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET ) //检查系统是否已从WWDG重置中恢复 { __HAL_RCC_CLEAR_RESET_FLAGS(); //清除重置标志 } __WWDG_CLK_ENABLE(); //使能窗口看门狗时钟 WwdgHandle.Instance = WWDG;//寄存器基址为 WWDG WwdgHandle.Init.Prescaler = WWDG_PRESCALER_8; //预分频 8kh WwdgHandle.Init.Window = 80;//窗口值 80 //指定要与自由下降计数器进行比较的WWDG窗口值。//此参数必须是小于Max_Data=0x80的数字 WwdgHandle.Init.Counter = 127; //自由下降计数器 //计数值, 7位计数值,最大值位127 HAL_WWDG_Init(&WwdgHandle); //窗口看门狗初始化 HAL_WWDG_Start_IT(&WwdgHandle); //启动窗口看门狗 HAL_NVIC_SetPriority(WWDG_IRQn,4,0); //设置中断优先级 //抢占 4 //响应 0 HAL_NVIC_EnableIRQ(WWDG_IRQn); //使能中断,选定中断源}void Wwdg_Feed(void){ HAL_WWDG_Refresh(&WwdgHandle,127); //喂狗也就是往里面重新定义值 最大127}void WWDG_IRQHandler(void)//外部中断服务函数,用来响应外部中断触发{ HAL_WWDG_IRQHandler(&WwdgHandle); //作用:1:清楚中断标记位// 2:调用回调函数}void HAL_WWDG_WakeupCallback(WWDG_HandleTypeDef* hwwdg){ if(Wwdg_ISR.Wwdg_Handle != NULL ) Wwdg_ISR.Wwdg_Handle(); //外部中断用户回调 //可以理解中断函数具体要响应的动作} |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1786 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1622 浏览 1 评论
1089 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
730 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1680 浏览 2 评论
1941浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
739浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
576浏览 3评论
598浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
560浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 11:20 , Processed in 0.980067 second(s), Total 76, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号