窗口看门狗就是必须在某个限定的时间段喂狗才不复位,喂早了喂晚了都不行。
为什么要这样的,就是怕用普通的喂狗,万一bug里自带喂狗就不好了,在一个狭窄的时间段里,这样程序的精确性会大大提高。
为啥叫窗口?
你听过窗口比较器么,还有滤波器(不过人家叫带通,带阻)
自己类比去吧,程序员的脑子,谁知道呢,害
工作原理
W是预设
T是倒计时
STM32F的窗口看门狗中有一个7位的递减计数器T[6:0],它会在出现下述2种情况之一时产生看门狗复位:
1. 当喂狗的时候如果计数器的值大于某一设定数值W[6:0]时,此设定数值在WWDG_CFR寄存器定义。
2. 当计数器的数值从0x40减到0x3F时【T6位跳变到0】 。
如果启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI),它可以用于喂狗以避免WWDG复位。
程序设计的思路一般都是在T[6:0]减到0x40时触发中断,喂狗,不然到0x3f就复位了。
寄存器及库函数
注意这里要除以4096!!!
常用库函数
分块对应上面寄存器
void WWDG_Enable(uint8_t Counter);//启动并设置初始值void WWDG_SetCounter(uint8_t Counter);//喂狗void WWDG_EnableIT(void);//使能提前唤醒中断void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);void WWDG_SetWindowValue(uint8_t WindowValue);FlagStatus WWDG_GetFlagStatus(void);void WWDG_ClearFlag(void); 配置步骤
为什么呢,因为我发现WWDG_Enable();位置不对的话会不停的复位。
使能时钟。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
设置预分频系数
注意:APB1默认时钟是36MHZ。
算这个除以分频系数还要除以4096。
WWDG_SetPrescaler(WWDG_Prescaler_8);
设置上窗口值
WWDG_SetWindowValue(0X5F);
使能窗口看门狗
这一步必须在这里,不然会一直复位。
我就是在这里想了半天。
我猜的原因是被当作喂狗了,所以一直复位(在窗口外)。
WWDG_Enable(0x7F);
清除中断标志位
WWDG_ClearFlag();
设置中断优先级NVIC
nvic_init(); void nvic_init(){ NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel=WWDG_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2; NVIC_InitStruct.NVIC_IRQChannelSubPriority=2; NVIC_Init(&NVIC_InitStruct); }
使能中断
WWDG_EnableIT(); 附:
死前中断
void WWDG_IRQHandler(){ WWDG_SetCounter(0x7F);// flg++; WWDG_ClearFlag(); GPIO_WriteBit(GPIOE,GPIO_Pin_5,!GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_5));}
窗口看门狗就是必须在某个限定的时间段喂狗才不复位,喂早了喂晚了都不行。
为什么要这样的,就是怕用普通的喂狗,万一bug里自带喂狗就不好了,在一个狭窄的时间段里,这样程序的精确性会大大提高。
为啥叫窗口?
你听过窗口比较器么,还有滤波器(不过人家叫带通,带阻)
自己类比去吧,程序员的脑子,谁知道呢,害
工作原理
W是预设
T是倒计时
STM32F的窗口看门狗中有一个7位的递减计数器T[6:0],它会在出现下述2种情况之一时产生看门狗复位:
1. 当喂狗的时候如果计数器的值大于某一设定数值W[6:0]时,此设定数值在WWDG_CFR寄存器定义。
2. 当计数器的数值从0x40减到0x3F时【T6位跳变到0】 。
如果启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI),它可以用于喂狗以避免WWDG复位。
程序设计的思路一般都是在T[6:0]减到0x40时触发中断,喂狗,不然到0x3f就复位了。
寄存器及库函数
注意这里要除以4096!!!
常用库函数
分块对应上面寄存器
void WWDG_Enable(uint8_t Counter);//启动并设置初始值void WWDG_SetCounter(uint8_t Counter);//喂狗void WWDG_EnableIT(void);//使能提前唤醒中断void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);void WWDG_SetWindowValue(uint8_t WindowValue);FlagStatus WWDG_GetFlagStatus(void);void WWDG_ClearFlag(void); 配置步骤
为什么呢,因为我发现WWDG_Enable();位置不对的话会不停的复位。
使能时钟。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
设置预分频系数
注意:APB1默认时钟是36MHZ。
算这个除以分频系数还要除以4096。
WWDG_SetPrescaler(WWDG_Prescaler_8);
设置上窗口值
WWDG_SetWindowValue(0X5F);
使能窗口看门狗
这一步必须在这里,不然会一直复位。
我就是在这里想了半天。
我猜的原因是被当作喂狗了,所以一直复位(在窗口外)。
WWDG_Enable(0x7F);
清除中断标志位
WWDG_ClearFlag();
设置中断优先级NVIC
nvic_init(); void nvic_init(){ NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel=WWDG_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2; NVIC_InitStruct.NVIC_IRQChannelSubPriority=2; NVIC_Init(&NVIC_InitStruct); }
使能中断
WWDG_EnableIT(); 附:
死前中断
void WWDG_IRQHandler(){ WWDG_SetCounter(0x7F);// flg++; WWDG_ClearFlag(); GPIO_WriteBit(GPIOE,GPIO_Pin_5,!GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_5));}
举报