STM32窗口看门狗_原子战舰WWDG例程学习笔记

针对学习STM32窗口看门狗和原子战舰所给的WWDG例程时候,存在的问题做如下记录。

1. WWDG超时公式推导

1.1 WWDG工作示意图


1.2 WWDG超时公式推导

(1) 上窗口的值可以只有设定,7位二进制数最大只可以设定为127(0x7F),最小又必须大于下窗口的0x40,所以其取值范围为64~127(即:0x40~0x7F

 

(2) 配置寄存器WWDG->CFR




窗口看门狗的时钟来自于PCLK1,在时钟配置中,其频率为外部时钟经倍频器后的二分频时钟,即为36MHz

 

(3)依据上述分析知,窗口时间计算公式为:

上窗口时间: T_min

=  (WWDG_CR[6:0] - WWDG_CFR[6:0])/(Tck/(2^WDGTB))(us)

=  (WWDG_CR[6:0] - WWDG_CFR[6:0])/((Tpck1/4096)/(2^WDGTB))(us)

=  4096 * (2^WDGTB)*(WWDG_CR[6:0] -WWDG_CFR[6:0])/(72/2) (us)

=  4096 *(2^WDGTB)*(WWDG_CR[6:0] - WWDG_CFR[6:0])/36 (us)

 

下窗口时间: T_max = 4096 * (2^WDGTB)*(WWDG_CR[6:0] - 0x3F)/36(us)

 

窗口看门狗的超时公式(刷新时间公式):

Twwdg = T_max - T_min

= 4096 *(2^WDGTB)*(WWDG_CFR[6:0] - 0x3F)/36 (us)

= 4096 *(2^WDGTB)*(WWDG_CFR[6:0] - 63)/36 (us)

又因为 WWDG_CFR[6:0]取值范围是:0~127,

(WWDG_CFR[6:0] –63)>0,

所以,

1<= (WWDG_CFR[6:0] – 63) <= 127-63=64

又因为 一个6位二进制X[5:0]数值范围是0~63,

1 <=  X[5:0]+1 <= 64

所以,

上式可以表述为:

Twwdg = 4096 * (2^WDGTB)*(T[5:0]+1)/36 (us)

  

4依据上式,可以计算出WWDG的定时时间范围:

WDGTB(计数器分频值)

最早喂狗时间/us

最晚喂狗时间/ms

0

113

7.28

1

227

14.56

2

455

29.12

3

910

58.25

2. 原子战舰WWDG库函数例程存在的问题

2.1 问题描述

        正常情况下,烧录原子战舰所提供的WWDG库函数(v3.5)例程,会看到起初红灯点亮,后熄灭,黄灯开始闪烁。但是,烧录该程序,只看到红灯闪烁。这说明了WWDG产生了中断,但是中断函数中的黄灯闪烁语句(LED1=~LED1)并没有执行。

2.2 问题解决

针对上述问题描述,可排除WWDG初始化错误的问题(因为红灯LED0在闪烁,说明WWDG已经产生的复位),定位到中断初始化失败或中断函数编写错误的问题。中断函数比较简单,检查后可以排除中断函数编写错误的问题。

下面,针对中断初始化函数进行检查。检查后,可以发现原例程中缺失了中断通道使能设置,即“NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;    //通道使能”。代码修改前后对比如下所示。修改后,再次烧录执行,会发现现象正常:起初红灯点亮,后熄灭,黄灯开始闪烁。

(1)中断初始化原始代码:

//WWDG中断初始化
void WWDG_NVIC_Init()
{
         NVIC_InitTypeDef NVIC_InitStructure;
         NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;    //WWDG中断
         //抢占2 子优先级3 组2
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  
         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  
         NVIC_Init(&NVIC_InitStructure);//NVIC 初始化
}

(2)中断初始化修改后代码:

//WWDG中断初始化
void WWDG_NVIC_Init()
{
         NVIC_InitTypeDef NVIC_InitStructure;
         NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;    //WWDG中断
     //抢占2 子优先级3 组2
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  
         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  
         NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;    //通道使能
         NVIC_Init(&NVIC_InitStructure);//NVIC 初始化
}

2.3 问题补充——WWDG初始化时库函数调用顺序

(1)对于下述的WWDG初始化函数,烧录后,运行正常。但是,将WWDG使能并装载初始值语句WWDG_Enable(WWDG_CNT)放于清除提前唤醒中断标志位语句WWDG_ClearFlag()和开启窗口看门狗中断语句WWDG_EnableIT()之后,再次执行,现象异常:只有红色灯在闪烁,黄色灯一直熄灭。

正确程序:

//保存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,u32 fprer)
{
         RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);  //   WWDG时钟使能
 
         WWDG_CNT=tr&WWDG_CNT;   //初始化WWDG_CNT.  
         WWDG_SetPrescaler(fprer);设置IWDG预分频值
         WWDG_SetWindowValue(wr);//设置窗口值
         WWDG_NVIC_Init();//初始化窗口看门狗 NVIC
WWDG_Enable(WWDG_CNT);    //使能WWDG 并装载初始值
         WWDG_ClearFlag();//清除提前唤醒中断标志位
         WWDG_EnableIT(); //开启窗口看门狗中断
}

异常程序: 

//保存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,u32 fprer)
{
         RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);  //   WWDG时钟使能
 
         WWDG_CNT=tr&WWDG_CNT;   //初始化WWDG_CNT.  
         WWDG_SetPrescaler(fprer);设置IWDG预分频值
         WWDG_SetWindowValue(wr);//设置窗口值
         WWDG_NVIC_Init();//初始化窗口看门狗 NVIC
         WWDG_ClearFlag();//清除提前唤醒中断标志位
         WWDG_EnableIT(); //开启窗口看门狗中断
         WWDG_Enable(WWDG_CNT);    //使能WWDG 并装载初始值
}

(2)错因分析

执行WWDG_Enable(WWDG_CNT)语句,会使能WWDG,并将初始值CNT装载至计数器中。执行此句,还会将WWDG_SR的EWIF置1,造成程序无法进入中断处理函数。

用JLINK在keil中对此进行单步调试可以发现,执行WWDG_Enable(WWDG_CNT)语句之后,WWDG_SR的EWIF被置1,如下图所示。

第一步:执行WWDG_Enable(WWDG_CNT)语句之前,状态寄存器WWDG_SR=0x0000,即EWIF=0

第二步: 执行WWDG_Enable(WWDG_CNT)语句之后,状态寄存器WWDG_SR=0x0001,即EWIF=1

(3)结论

WWDG使能函数必须在WWDG清除提前唤醒中断标志位和开启窗口看门狗中断之前执行。

 

 

 

 

 

 

 

 

 

 


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值