OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3245|回复: 3

窗口看门狗的代码疑问

[复制链接]

9

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2015-8-18
在线时间
17 小时
发表于 2016-2-24 18:07:40 | 显示全部楼层 |阅读模式
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 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

1097

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3571
金钱
3571
注册时间
2014-12-2
在线时间
365 小时
发表于 2016-2-24 18:07:41 | 显示全部楼层
1、
WWDG_CNT=tr&WWDG_CNT;
这一段代码是对输入参数 tr 的有效性核验,即保留tr的低7位,但这样写是在不妥,有歧义,推荐写法:
[mw_shl_code=c,true]WWDG_CNT = tr & WWDG_CR_T;[/mw_shl_code]
(WWDG_CR_T 是STM32芯片头文件提供的标准掩码,不必担心发生未定义错误)
---------分割------
WWDG->CR|=WWDG_CNT;
窃以为这段代码错了,我查看此例程的库函数版本,把那个“|”去掉!

另外,重置计数器这一句:
WWDG->CR =(cnt&0x7F);
感觉也不太妥当,我更喜欢如下写法:
[mw_shl_code=c,true]WWDG->CR = WWDG_CR_WDGA | (cnt&WWDG_CR_T);[/mw_shl_code]
虽然 WWDG_CR_WDGA 一旦被软件设置就无法清除,
初始化后设置CR寄存器是是否设置它功能上无任何影响,
但显性地用代码写出来可以防止日后看到这一行感到困惑。



坚决不用寄存器,拒绝重复造轮子。
回复

使用道具 举报

9

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2015-8-18
在线时间
17 小时
 楼主| 发表于 2016-2-24 23:07:00 | 显示全部楼层
xkwy 发表于 2016-2-24 18:07
1、
这一段代码是对输入参数 tr 的有效性核验,即保留tr的低7位,但这样写是在不妥,有歧义,推荐写法:
...

谢谢,终于明白了
回复

使用道具 举报

5

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
254
金钱
254
注册时间
2015-8-25
在线时间
27 小时
发表于 2016-2-25 11:27:48 | 显示全部楼层
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-20 22:55

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表