|
|
實驗現(xiàn)象:
這是基于窗口看門狗的實驗,剛開始初始化時LED2閃了一下,后來就保持亮著,而LED1卻不斷的在閃爍,這是因為中斷函數(shù)運(yùn)行的緣故。
實驗平臺:
基于STM32F103C8T6的彩屏開發(fā)板
實驗步驟:
1)使能WWDG 時鐘
WWDG 不同于IWDG,IWDG 有自己獨(dú)立的40Khz 時鐘,不存在使能問題。而WWDG
使用的是PCLK1 的時鐘,需要先使能時鐘。
2)設(shè)置WWDG_CFR 和WWDG_CR 兩個寄存器
在時鐘使能完后,我們設(shè)置 WWDG 的CFR 和CR 兩個寄存器,對WWDG 進(jìn)行配置。包
括使能窗口看門狗、開啟中斷、設(shè)置計數(shù)器的初始值、設(shè)置窗口值并設(shè)置分頻數(shù)WDGTB 等。
3)開啟WWDG 中斷并分組
在設(shè)置完了 WWDG 后,需要配置該中斷的分組及使能。這點(diǎn)通過我們之前所編寫的
MY_NVIC_Init 函數(shù)實現(xiàn)就可以了。
4)編寫中斷服務(wù)函數(shù)
在最后,還是要編寫窗口看門狗的中斷服務(wù)函數(shù),通過該函數(shù)來喂狗,喂狗要快,否則當(dāng)
窗口看門狗計數(shù)器值減到0X3F 的時候,就會引起軟復(fù)位了。在終端服務(wù)函數(shù)里面也要將狀態(tài)
寄存器的EWIF 位清空。
實驗代碼:
wwdg.h
#ifndef WWDG_H
#define WWDG_H
void WWDG_Init(u8,u8,u8);//聲明看門狗的初始化函數(shù)
void WWDG_Reset(void);//重新給遞減計數(shù)器賦值
#endif
wwdg.c
#include"common.h"
#include"wwdg.h"
#include"led.h"
//tr :T[6:0],用于存儲計數(shù)器的值
//wr :W[6:0],用于存儲窗口值
//fprer:窗口看門狗的實際設(shè)置
u8 WWDG_CNT=0x7f;
void WWDG_Init(u8 tr ,u8 wr,u8 fprer )
{
RCC->APB1ENR|=1<<11; //開啟窗口看門狗的時鐘
WWDG_CNT=tr&WWDG_CNT; //主要是為了防止用戶寫錯數(shù)據(jù)造成巨大偏差
WWDG->CFR|=fprer<<7; //預(yù)分頻時基設(shè)置
WWDG->CFR|=1<<9; //開啟提前喚醒中斷
WWDG->CFR&=0xff8; //保證上面兩個設(shè)置的正確性
WWDG->CFR|=wr; //給遞減計數(shù)器賦初值
WWDG->CR|=WWDG_CNT; //給窗口寄存器賦值
WWDG->CR|=1<<7; //啟用看門狗
MY_NVIC_Init(2,3,WWDG_IRQChannel,2);//設(shè)置中斷的分組和優(yōu)先級
}
//重新給遞減計數(shù)器賦值
void WWDG_Reset(void)
{
WWDG->CR=0x7f;
}
//中斷服務(wù)函數(shù)
void WWDG_IRQHandler(void)
{
u8 tr,wr;
tr=(WWDG->CR&0x7f);//讀取窗口寄存器的值
wr=(WWDG->CFR&0x7f);//讀取遞減計數(shù)器的值
if(tr<wr)//當(dāng)遞減計數(shù)器的值小于窗口的才能給遞減計數(shù)器重新復(fù)制,不然會復(fù)位的
WWDG_Reset();
WWDG->SR=0x0; //去除提前喚醒中斷標(biāo)志
LED1=!LED1; //LED反向
}
第一個函數(shù)void WWDG_Init(u8 tr,u8 wr,u8 fprer)用來
設(shè)置WWDG的初始化值。包括看門狗計數(shù)器的值和看門狗比較值等。注意到這里有個全局變量WWDG_CNT,該變量用來保存最初設(shè)置WWDG_CR計數(shù)器的值。在后續(xù)的中斷服務(wù)函數(shù)里面,就又把該數(shù)值放回到WWDG_CR上。
WWDG_Set_Counter 函數(shù)比較簡單,就是用來復(fù)位窗口看門狗的計數(shù)器值的。該函數(shù)很簡
單。
最后中斷服務(wù)函數(shù)里面,一定要先比較窗口計數(shù)器的值是否小于看門狗的窗口值,如果不
小于,則不要修改,如果小于,才能進(jìn)行修改。我們通過LED1 不停的取反,來觀測中斷服務(wù)函
數(shù)的執(zhí)行了狀況。我們再把這幾個函數(shù)名加入到頭函數(shù)里面去,以方便其他文件調(diào)用。
主函數(shù)
#include<stm32f10x_lib.h>
#include"common.h"
#include"led.h"
#include"key.h"
#include"wwdg.h"
int main(void)
{
Stm32_Clock_Init(9); //系統(tǒng)時鐘設(shè)置
delay_init(72); //延時初始化
LED_Init(); //LED初始化
KEY_Init(); //按鍵的初始化
WWDG_Init(0x7f,0x5f,3);
LED2=0;
delay_ms(300);
while(1)
{
LED2=1;
}
}
|
|