獨立看門狗(IWDG)的設計初衷是為了檢測和解決由軟件錯誤所引起的故障,與窗口看門狗的主要區別在于獨立看門狗可以作為一個處于主程序之外,由內部低速時鐘(LSI)驅動,能夠完全獨立工作的模塊,當主時鐘發生故障或芯片處在低功耗模式的時候,獨立看門狗依舊可以繼續工作。
它的原理可以簡述為:當獨立看門狗計數器不斷遞減達到給定數值時,將產生一個系統復位信號使系統復位或產生中斷信號。
MM32F0140的獨立看門狗有一個特色功能,用戶可以通過配置選擇IWDG產生復位還是產生中斷功能,比如在stop模式下,用戶可以選擇中斷方式喚醒從而不用復位MCU,SRAM數據不用因為看門狗喚醒而被清除。
1產生復位或者中斷
MM32F014x的獨立看門狗內部是自由運行的12位遞減計數器,當設置IWDG復位方式時,當計數達到0x0000時,會產生一個系統復位;當設置IWDG中斷方式時,當設置看門狗中斷生成值IGEN,每當計數器值遞減等于該值時,會產生一個中斷信號。
2計數器時鐘
IWDG是由低速時鐘源(LSI)驅動,經過IWDG_PR預分頻器分頻得到,預分頻因子可以被設置為4,8,16,32,64,128,256,在開啟IWDG前需要先開啟LSI,如圖1所示。
圖1
3重裝載寄存器
每次執行喂狗操作,就會將重裝載寄存器(IWDG_RLR)的值重新加載到計數器中,從而避免產生復位或者中斷信號,該操作通常叫做喂狗操作。復位時重裝載寄存器(IWDG_RLR)的值為0xFFF,如圖2。
圖2
4看門狗超時時間
IWDG的超時周期可以通過重裝載寄存器(IWDG_RLR)的值和預分頻寄存器(IWDG_PR)計算得到,公式如下:
Tout(ms)=((4×2^PR)×RLR)/40
當IWDG_RLR寄存器為最大值時,可以獲得最長的超時時間,參考時間如表1:
表1
5寄存器保護
獨立看門狗中的IWDG_PR,IWDG_RLR,IWDG_IGEN寄存器具有訪問保護功能,只能在向鍵值寄存器(IWDG_KR)寫入0x5555,才能修改以上被保護的寄存器的值。向鍵值寄存器寫入其他值或者重載操作時,寄存器依舊出在保護狀態。
6看門狗中斷
當開啟獨立看門狗后,計數器開始從其復位值0xFFF開始遞減,當IWDG_CR控制寄存器中的IRQ_SEL位置1時,計數器遞減到IWDG_IGEN設定的值后會產生一個中斷。獨立看門狗中斷被連接到EXTI24上,所以看門狗中斷可以使MCU從低功耗模式下喚醒,結合IWDG_IGEN寄存器的設定,可以模擬低功耗定時器來使用。
7部分庫函數參考
PVU_CheckStatus();
IWDG_SetPrescaler(IWDG_Prescaler);
修改預分頻寄存器(IWDG_PR),修改前需要先向鍵值寄存器(IWDG_KR)寫入0x5555。
RVU_CheckStatus();
IWDG_WriteAccessCmd(0x5555);
IWDG_SetReload(Reload & 0xfff);
修改重裝載寄存器(IWDG_RLR),修改前需要先向鍵值寄存器(IWDG_KR)寫入0x5555。
IVU_CheckStatus();
IWDG_WriteAccessCmd(0x5555);
IWDG_SetIGen(0x7ff);
修改中斷生成寄存器(IWDG_IGEN),修改前需要先向鍵值寄存器(IWDG_KR)寫入0x5555。
IWDG_EnableIT();
開啟看門狗中斷,如果需要看門狗復位方式需要設置:IWDG_Reset();
IWDG_ReloadCounter();
IWDG_Enable();
重載計數器、開啟IWDG計數器。
IWDG_ClearITPendingBit();
清除看門狗中斷標志位。
8程序配置
8.1 開啟獨立看門狗
開啟看門狗前需要先打開LSI,配置預分頻寄存器,配置重裝載寄存器,然后開啟IWDG計數器,以下示例代碼對IWDG進行初始化,配置預分頻因子為16,重裝載寄存器從最大值(0xFFF)開始計數,最大看門狗超時時間大概為1.6秒,代碼如下:
voidIWDG_Init(void)
{
//開啟低速時鐘,等待時鐘穩定
RCC_LSICmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)==RESET);
//設置預分頻寄存器
PVU_CheckStatus();
IWDG_WriteAccessCmd(0x5555);
IWDG_SetPrescaler(0x02);//選擇對LSI進行16分頻
//設置重裝載寄存器
RVU_CheckStatus();
IWDG_WriteAccessCmd(0x5555);
IWDG_SetReload(0xfff);//重裝載寄存器設置為0xFFF
//將重裝載寄存器的值加載到計數器,并開啟計數器
IWDG_ReloadCounter();
IWDG_Enable();
}
8.2 重裝載計數器(喂狗)
在任何時候向IWDG_KR寄存器寫入0xAAAA,就會將重裝載寄存器(IWDG_RLR)中的值加載到計數器中,避免產生復位或者中斷,可以使用如下庫函數:
IWDG_ReloadCounter();
或者直接操作寄存器,但要特別注意,在喂狗后最多需要5個LSI的振蕩周期。
IWDG->KR = 0xAAAA;
8.3 開啟看門狗中斷
如需要開啟看門狗中斷,在配置IWDG時需要配置IWDG_CR中的IRQ_SEL和IWDG_IGEN寄存器,在開啟看門狗之前加入如下代碼:
1)配置中斷生成寄存器(IWDG_IGEN),并開啟看門狗中斷
IVU_CheckStatus();
IWDG_WriteAccessCmd(0x5555);
IWDG_SetIGen(0x7FF);//將IWDG_IGEN配置為0x7FF,當計數器到該值時會產生中斷
IWDG_EnableIT();
2)使能NVIC和外部中斷源
{
EXTI_InitTypeDefEXTI_InitStruct;
NVIC_InitTypeDefNVIC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1ENR_PWR,ENABLE);
//EnabletheIWDGInterrupt
NVIC_InitStruct.NVIC_IRQChannel=WWDG_IWDG_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority=0;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
RCC_APB2PeriphClockCmd(RCC_APB2RSTR_SYSCFG,ENABLE);
EXTI_StructInit(&EXTI_InitStruct);
EXTI_ClearITPendingBit(EXTI_Line24);
//IWDGmaptoEXTI_Line24
EXTI_InitStruct.EXTI_Line=EXTI_Line24;
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;
EXTI_InitStruct.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStruct);
}
3)編寫看門狗中斷服務函數,由于和窗口看門狗共用一個中斷源,所以庫中函數名和窗口看門狗一致。
voidWWDG_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line24)!=RESET)
{
EXTI_ClearITPendingBit(EXTI_Line24);
IWDG_ClearIT();
IWDG_ReloadCounter();//可以在中斷中喂狗或者置標志位
}
}
9功能驗證
在測試驗證程序中在看門狗中斷服務函數添加printf("IWDG IRQ Mode ");下載程序可以看到MCU上電完成后會一直循環打印“IWDG IRQ Mode”。
圖3
針對需要短時間低功耗STOP模式喚醒的應用場景,可以使用該方式喚醒,同時針對LSI精度不高的問題,可以通過HSI對LSI進行校準方式,從而獲取高精度的LSI時鐘源。
-
看門狗
+關注
關注
10文章
565瀏覽量
70819 -
計數器
+關注
關注
32文章
2256瀏覽量
94614 -
IWDG
+關注
關注
0文章
21瀏覽量
5223 -
獨立看門狗
+關注
關注
0文章
24瀏覽量
3840 -
MM32
+關注
關注
1文章
106瀏覽量
774
原文標題:靈動微課堂 (第222講) | MM32F0140學習筆記——獨立看門狗(IWDG)
文章出處:【微信號:MindMotion-MMCU,微信公眾號:靈動MM32MCU】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論