窗口看门狗的开启与提前唤醒中断顺序问题

2019-10-14 20:33发布

本帖最后由 kingpage 于 2016-3-4 15:23 编辑

按照原子所提供的窗口看门狗的代码如下:
[mw_shl_code=c,true]//保存WWDG计数器的设置值,默认为最大.
u8 WWDG_CNT=0x7f;
//初始化窗口看门狗        
//tr   :T[6:0],计数器值
//wr   :W[6:0],窗口值
//fprer:分频系数(WDGTB),仅最低2位有效
//Fwwdg=PCLK1/(4096*2^fprer).
void WWDG_Init(u8 tr,u8 wr,u8 fprer)
{   
        RCC->APB1ENR|=1<<11;         //使能wwdg时钟
        WWDG_CNT=tr&WWDG_CNT;   //初始化WWDG_CNT.     
        WWDG->CFR|=fprer<<7;    //PCLK1/4096再除2^fprer
        WWDG->CFR&=0XFF80;      
        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;        //使能提前唤醒中断
       
}
//重设置WWDG计数器的值
void WWDG_Set_Counter(u8 cnt)
{
        WWDG->CR =(cnt&0x7F);//重设置7位计数器
}
//窗口看门狗中断服务程序
void WWDG_IRQHandler(void)
{      
        WWDG_Set_Counter(WWDG_CNT);//重设窗口看门狗的值!         
        WWDG->SR=0X00;//清除提前唤醒中断标志位
        LED1=!LED1;
}[/mw_shl_code]
其中,在看门狗初始化WWDG_Init函数中,按照这样的代码顺序是没问题的,能正常地进入WWDG_IRQHandler函数进行喂狗。但如果把WWDG_Init函数中的WWDG->CR|=1<<7; //开启看门狗.这一行代码的位置放到同样是WWDG_Init函数:
[mw_shl_code=c,true]MY_NVIC_Init(2,3,WWDG_IRQn,2);//抢占2,子优先级3,组2
WWDG->SR=0X00; //清除提前唤醒中断标志位
WWDG->CFR|=1<<9; //使能提前唤醒中断[/mw_shl_code]
中的任何一行代码后面,例如初始化代码改为:
[mw_shl_code=c,true]void WWDG_Init(u8 tr,u8 wr,u8 fprer)
{   
        RCC->APB1ENR|=1<<11;         //使能wwdg时钟
        WWDG_CNT=tr&WWDG_CNT;   //初始化WWDG_CNT.     
        WWDG->CFR|=fprer<<7;    //PCLK1/4096再除2^fprer
        WWDG->CFR&=0XFF80;      
        WWDG->CFR|=wr;                     //设定窗口值      
        WWDG->CR|=WWDG_CNT;         //设定计数器值
   
        MY_NVIC_Init(2,3,WWDG_IRQn,2);//抢占2,子优先级3,组2     
        WWDG->SR=0X00;                         //清除提前唤醒中断标志位
        WWDG->CFR|=1<<9;        //使能提前唤醒中断

        WWDG->CR|=1<<7;                  //开启看门狗
       
} [/mw_shl_code]
看门狗就会出现不断地产生复位的情况。按照我的理解应该是把看门狗所有的配置(包括它相关的寄存器以及中断分组等)都设置好,再开启看门狗才是个正确的代码运行顺序啊,为何"开启看门狗"这句代码放在后面就会产生不断复位的问题?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
16条回答
Da Wen
1楼-- · 2019-10-14 23:25
本帖最后由 Da Wen 于 2016-3-10 09:33 编辑

  使能窗口看门狗的时候,WWDG_SR中的EWIF位就马上被置位了(具体为什么我也不清楚),加上我们使能了中断,所以程序会马上进入中断。我们在中断服务程序里面喂狗,按原子哥的看门狗例程[mw_shl_code=c,true]WWDG_Init(0X7F,0X5F,3);        //计数器值为7f,窗口寄存器为5f,分频数为8         [/mw_shl_code]  ,窗口的值比计数器的值小(我们的中断服务程序是在窗口外重新加载计数器),所以就马上复位了。
解决方法有两个:
一、在初始化看门狗的时候,窗口的值比计数器的重装值大。[mw_shl_code=c,true]WWDG_Init(0x70,0x7e,WWDG_Prescaler_8);[/mw_shl_code]
二、在使能看门狗之后,先清除一下中断标志位,然后再使能中断。(这时候窗口的值在初始化的时候就可以比计数器的值小)
[mw_shl_code=c,true]uint8_t WWDG_CNT = 0x7f;

void WWDG_Init(uint8_t tr,uint8_t wr,uint32_t fprer)
{
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
        
        WWDG_CNT = tr & WWDG_CNT; ///设置重装值
        WWDG_SetPrescaler(fprer);//设置分频系数
        
        WWDG_SetWindowValue(wr);//设置窗口的值
        
        
        WWDG_NVIC_Init(); //配置中断优先级
        
        WWDG_Enable(WWDG_CNT);//使能看门狗
        WWDG_ClearFlag(); //清除中断标志位
        WWDG_EnableIT(); //使能中断
}[/mw_shl_code]
caojiasheng
2楼-- · 2019-10-14 23:34
我也是刚碰到这样的问题
kingpage
3楼-- · 2019-10-14 23:49
caojiasheng 发表于 2016-3-4 18:22
我也是刚碰到这样的问题

原来不止我一个碰上这问题了。有没有高手解答一下呢?
正点原子
4楼-- · 2019-10-15 00:39
 精彩回答 2  元偷偷看……
kingpage
5楼-- · 2019-10-15 00:52
正点原子 发表于 2016-3-5 22:57
窗口看门狗的代码,不要随意改,很容易出问题。至于为什么,我也不知道

原来连原子哥也不知道
单模先声
6楼-- · 2019-10-15 02:58
一开始看到问题时我也蒙了,然后往下拉,看到原子哥也不会我就开心了

一周热门 更多>