初级会员

- 积分
- 119
- 金钱
- 119
- 注册时间
- 2015-8-18
- 在线时间
- 17 小时
|
1金钱
窗口看门狗代码如下:
[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_CNT有几个不明白的地方。以我调用的初始化方法参数为:WWDG_Init(0X7E,0X5F,3)为例 书上的是:WWDG_Init(0X7F,0X5F,3);)
1、在初始化WWDG_Init方法中:
WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT.此时的WWDG_CNT=0X7E&0X7F,值为:0X7E,二进制:0111 1110
WWDG->CR|=WWDG_CNT; //设定计数器值.WWDG->CR默认值为0X7F,即:WWDG->CR=0X7F|0X7E,值为:0X7F,二进制:0111 1111
那么初始化后,最终的WWDG_CNT值为:0X7E.WWDG->CR的值为0X7F,与默认值没任何改变
2、中断处理函数WWDG_IRQHandler方法中:
WWDG_Set_Counter(WWDG_CNT);//重设窗口看门狗的值!
3、在重置计数器方法WWDG_Set_Counter中:
WWDG->CR =(cnt&0x7F);//重设置7位计数器 .cnt参数值为WWDG_CNT,即:WWDG->CR=0X7E&0X7F,值为:0X7E,二进制:0111 1110
重置后,WWDG->CR的值为:0X7E
这里的代码是我搞错了,还是有BUG呢,在初始化(WWDG_Init)的时候,WWDG->CR的值为0X7F,但在重置计数器的时候(WWDG_Set_Counter)中,就会变成了0X7E了,这样就会引起喂狗后计数器的值跟初始化时的值不一样了.如果初始化时,tw的参数值用的是书上的0X7F是不会发现这个问题.
为什么在初始化(WWDG_Init)时不直接把WWDG_CNT=tw;WWDG->CR=WWDG_CNT,重置(WWDG_Set_Counter)时就把WWDG->CR=cnt呢?这样就不会引起喂狗后计数器的值与初始化所设置的不一样了。请大家指点一下?
|
最佳答案
查看完整内容[请看2#楼]
1、
这一段代码是对输入参数 tr 的有效性核验,即保留tr的低7位,但这样写是在不妥,有歧义,推荐写法:
[mw_shl_code=c,true]WWDG_CNT = tr & WWDG_CR_T;[/mw_shl_code]
(WWDG_CR_T 是STM32芯片头文件提供的标准掩码,不必担心发生未定义错误)
---------分割------
窃以为这段代码错了,我查看此例程的库函数版本,把那个“|”去掉!
另外,重置计数器这一句:
感觉也不太妥当,我更喜欢如下写法:
[mw_shl_code=c,tr ...
|