stm32看门狗_「正点原子NANO STM32开发板资料连载」第十一章 独立看门狗实验
1)實(shí)驗(yàn)平臺(tái):ALIENTEK NANO STM32F411 V1開(kāi)發(fā)板2)摘自《正點(diǎn)原子STM32F4 開(kāi)發(fā)指南(HAL 庫(kù)版》關(guān)注官方微信號(hào)公眾號(hào),獲取更多資料:正點(diǎn)原子
第十一章 獨(dú)立看門(mén)狗(IWDG)實(shí)驗(yàn)
這一章,我們將向大家介紹如何使用 STM32 的獨(dú)立看門(mén)狗(以下簡(jiǎn)稱(chēng) IWDG)。STM32F4
內(nèi)部自帶了 2 個(gè)看門(mén)狗:獨(dú)立看門(mén)狗(IWDG)和窗口看門(mén)狗(WWDG)。這一章我們只介紹
獨(dú)立看門(mén)狗,窗口看門(mén)狗將在下一章介紹。在本章中,我們將通過(guò)按鍵 KEY_UP 來(lái)喂狗,然后
通過(guò) DS0 提示復(fù)位狀態(tài)。本章分為如下幾個(gè)部分:
11.1 STM32F4 獨(dú)立看門(mén)狗簡(jiǎn)介
11.2 硬件設(shè)計(jì)
11.3 軟件設(shè)計(jì)
11.4 下載驗(yàn)證
11.5 STM32CubeMX 配置 IWDG11.1 STM32F4 獨(dú)立看門(mén)狗簡(jiǎn)介
STM32 的獨(dú)立看門(mén)狗由內(nèi)部專(zhuān)門(mén)的 32Khz 低速時(shí)鐘(LSI)驅(qū)動(dòng),即使主時(shí)鐘發(fā)生故障,
它也仍然有效。這里需要注意獨(dú)立看門(mén)狗的時(shí)鐘是一個(gè)內(nèi)部 RC 時(shí)鐘,所以并不是準(zhǔn)確的 32Khz,
而是在 15~47Khz 之間的一個(gè)可變化的時(shí)鐘,只是我們?cè)诠浪愕臅r(shí)候,以 32Khz 的頻率來(lái)計(jì)算,
看門(mén)狗對(duì)時(shí)間的要求不是很精確,所以,時(shí)鐘有些偏差,都是可以接受的。
獨(dú)立看門(mén)狗有幾個(gè)寄存器與我們這節(jié)相關(guān),我們分別介紹這幾個(gè)寄存器,首先是鍵值寄存
器 IWDG_KR,該寄存器的各位描述如圖 11.1.1 所示:
圖 11.1.1 IWDG_KR 寄存器各位描述
在鍵值寄存器(IWDG_KR)中寫(xiě)入 0xCCCC,開(kāi)始啟用獨(dú)立看門(mén)狗;此時(shí)計(jì)數(shù)器開(kāi)始從其復(fù)
位值 0xFFF 遞減計(jì)數(shù)。當(dāng)計(jì)數(shù)器計(jì)數(shù)到末尾 0x000 時(shí),會(huì)產(chǎn)生一個(gè)復(fù)位信號(hào)(IWDG_RESET)。
無(wú)論何時(shí),只要鍵寄存器 IWDG_KR 中被寫(xiě)入 0xAAAA, IWDG_RLR 中的值就會(huì)被重新加載
到計(jì)數(shù)器中從而避免產(chǎn)生看門(mén)狗復(fù)位 。
IWDG_PR 和 IWDG_RLR 寄存器具有寫(xiě)保護(hù)功能。要修改這兩個(gè)寄存器的值,必須先向
IWDG_KR 寄存器中寫(xiě)入 0x5555。將其他值寫(xiě)入這個(gè)寄存器將會(huì)打亂操作順序,寄存器將重新
被保護(hù)。重裝載操作(即寫(xiě)入 0xAAAA)也會(huì)啟動(dòng)寫(xiě)保護(hù)功能。
接下來(lái),我們介紹預(yù)分頻寄存器(IWDG_PR),該寄存器用來(lái)設(shè)置看門(mén)狗時(shí)鐘的分頻系數(shù),
最低為 4,最高位 256,該寄存器是一個(gè) 32 位的寄存器,但是我們只用了最低 3 位,其他都是
保留位。預(yù)分頻寄存器各位定義如圖 11.1.2 所示:
圖 11.1.2 IWDG_ PR 寄存器各位描述
在介紹完 IWDG_PR 之后,我們介紹一下重裝載寄存器。該寄存器用來(lái)保存重裝載到計(jì)數(shù)
器中的值。該寄存器也是一個(gè) 32 位寄存器,但是只有低 12 位是有效的,該寄存器的各位描述
如圖 11.1.3 所示:
圖 11.1.3 重裝載寄存器各位描述
只要對(duì)以上三個(gè)寄存器進(jìn)行相應(yīng)的設(shè)置,我們就可以啟動(dòng) STM32F4 的獨(dú)立看門(mén)狗,獨(dú)立
看門(mén)狗相關(guān)的 HAL 庫(kù)操作函數(shù)在文件 stm32f4xx_hal_iwdog.c 和頭文件 stm32f4xx_hal_iwdg.h
中。接下來(lái)我們講解一下通過(guò) HAL 庫(kù)配置獨(dú)立看門(mén)狗的步驟:1)取消寄存器寫(xiě)保護(hù),設(shè)置看門(mén)狗預(yù)分頻系數(shù)和重裝載值,并啟動(dòng)看門(mén)狗
首先我們必須取消 IWDOG_PR 和 IWDG_RLR 寄存器的寫(xiě)保護(hù),這樣才可以設(shè)置寄存器
IWDG_PR 和 IWDG_RLR 的值。取消寫(xiě)保護(hù)和設(shè)置預(yù)分配系數(shù)以及重裝載值在 HAL 庫(kù)中是通
過(guò)函數(shù) HAL_IWDG_Init 實(shí)現(xiàn)的。該函數(shù)聲明為:
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg);
該函數(shù)只有一個(gè)入口參數(shù) hiwdg,該函數(shù)是 IWDG_HandleTypeDef 結(jié)構(gòu)體指針類(lèi)型。接下
來(lái)我們看看結(jié)構(gòu)體 IWDG_HandleTypeDef 定義:
typedef struct
{
IWDG_TypeDef
*Instance;
IWDG_InitTypeDef
Init;
}IWDG_HandleTypeDef;
成員變量 Instance 用來(lái)設(shè)置看門(mén)狗寄存器基地址,實(shí)際上在 HAL 庫(kù)中已經(jīng)通過(guò)標(biāo)識(shí)符定義
了,這里對(duì)于獨(dú)立看門(mén)狗直接設(shè)置為標(biāo)識(shí)符 IWDG 即可。
成員變量 Init 是一個(gè) IWDG_InitTypeDef 結(jié)構(gòu)體類(lèi)型,該結(jié)構(gòu)體只有 2 個(gè)成員變量,分別
用來(lái)設(shè)置獨(dú)立看門(mén)狗的預(yù)分頻系數(shù)和重裝載值,定義如下:
typedef struct
{
uint32_t Prescaler;
uint32_t Reload;
} IWDG_InitTypeDef;
HAL_IWDG_Init 函數(shù)使用的一般方法為:
IWDG_HandleTypeDef IWDG_Handler; //獨(dú)立看門(mén)狗句柄
IWDG_Handler.Instance=IWDG;
//獨(dú)立看門(mén)狗
IWDG_Handler.Init.Prescaler=IWDG_PRESCALER_64;
//設(shè)置 IWDG 分頻系數(shù)
IWDG_Handler.Init.Reload=625;
//重裝載值
HAL_IWDG_Init(&IWDG_Handler);
//初始化 IWDG,默認(rèn)會(huì)開(kāi)啟獨(dú)立看門(mén)狗
上面程序的作用是初始化 IWDG,設(shè)置分頻系數(shù)為 64,重裝載值為 500。設(shè)置完預(yù)分頻系
數(shù)和重裝載值后,我們就可以知道看門(mén)狗的喂狗時(shí)間(也就是看門(mén)狗溢出時(shí)間),該時(shí)間的計(jì)
算方式為:
Tout=((4×2^prer) ×rlr) /32
其中 Tout 為看門(mén)狗溢出時(shí)間(單位為 ms);prer 為看門(mén)狗時(shí)鐘預(yù)分頻值(IWDG_PR 值),
范圍為 0~7;rlr 為看門(mén)狗的重裝載值(IWDG_RLR 的值);
比如我們?cè)O(shè)定 prer 值為 4(4 代表的是 64 分頻,HAL 庫(kù)中可以使用宏定義標(biāo)識(shí)符
IWDG_PRESCALER_64),rlr 值為 500,那么就可以得到 Tout=64×500/32=1000ms,這樣,看
門(mén)狗的溢出時(shí)間就是 1s,只要你在一秒鐘之內(nèi),有一次寫(xiě)入 0XAAAA 到 IWDG_KR,就不會(huì)
導(dǎo)致看門(mén)狗復(fù)位(當(dāng)然寫(xiě)入多次也是可以的)。這里需要提醒大家的是,看門(mén)狗的時(shí)鐘不是準(zhǔn)
確的 40Khz,所以在喂狗的時(shí)候,最好不要太晚了,否則,有可能發(fā)生看門(mén)狗復(fù)位。
內(nèi)部初始化 IWDG 后,同時(shí)會(huì)啟動(dòng)看門(mén)狗(IWDG_KR 寫(xiě)入 0XCCCC)。2)重載計(jì)數(shù)值喂狗(向 IWDG_KR 寫(xiě)入 0XAAAA)
在 HAL 中重載計(jì)數(shù)值函數(shù)是 HAL_IWDG_Refresh,該函數(shù)聲明為:
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg);
該函數(shù)有一個(gè)入口參數(shù)為前面所講的 IWDG_HandleTypeDef 結(jié)構(gòu)體類(lèi)型指針,它的作用是
把值 0xAAAA 寫(xiě)入到 IWDG_KR 寄存器,從而觸發(fā)計(jì)數(shù)器重載,及實(shí)現(xiàn)獨(dú)立看門(mén)狗的喂狗操作。3)啟動(dòng)看門(mén)狗(向 IWDG_KR 寫(xiě)入 0XAAAA)
HAL 庫(kù)函數(shù)里面啟動(dòng)獨(dú)立看門(mén)狗的函數(shù)是 HAL_IWDG_Start:
HAL_StatusTypeDef HAL_IWDG_Start(IWDG_HandleTypeDef *hiwdg);
通過(guò)上面 3 個(gè)步驟,我們就可以啟動(dòng) STM32F4 的看門(mén)狗了,使能了看門(mén)狗,在程序里面
就必須間隔一定時(shí)間喂狗,否則將導(dǎo)致程序復(fù)位。利用這一點(diǎn),我們本章將通過(guò)一個(gè) LED 燈來(lái)
指示程序是否重啟,來(lái)驗(yàn)證 STM32F4 的獨(dú)立看門(mén)狗。
在配置看門(mén)狗后,DS0 將常亮,如果 KEY_UP 按鍵按下,就喂狗,只要 KEY_UP 不停的
按,看門(mén)狗就一直不會(huì)產(chǎn)生復(fù)位,保持 DS0 的常亮,一旦超過(guò)看門(mén)狗定溢出時(shí)間(Tout)還沒(méi)
按,那么將會(huì)導(dǎo)致程序重啟,這將導(dǎo)致 DS0 熄滅一次。11.2 硬件設(shè)計(jì)
本實(shí)驗(yàn)用到的硬件資源有:
1) 指示燈 DS0
2) WK_UP 按鍵
3) 獨(dú)立看門(mén)狗
前面兩個(gè)在之前都有介紹,而獨(dú)立看門(mén)狗實(shí)驗(yàn)的核心是在 STM32F4 內(nèi)部進(jìn)行,并不需要
外部電路。但是考慮到指示當(dāng)前狀態(tài)和喂狗等操作,我們需要 2 個(gè) IO 口,一個(gè)用來(lái)輸入喂狗
信號(hào),另外一個(gè)用來(lái)指示程序是否重啟。喂狗我們采用板上的 KEY_UP 鍵來(lái)操作,而程序重啟,
則是通過(guò) DS0 來(lái)指示的。11.3 軟件設(shè)計(jì)
我們直接打開(kāi)光盤(pán)的獨(dú)立看門(mén)狗實(shí)驗(yàn)工程,可以看到工程里面新增了 iwdg.c,同時(shí)引入了
頭文件 iwdg.h。同樣的道理,我們要加入 HAL 庫(kù)看門(mén)狗支持文件 stm32f4xx_hal_iwdg.h 和
stm32f4xx_hal_iwdg.c 文件。
iwdg.c 里面的代碼如下:
#include "iwdg.h"
IWDG_HandleTypeDef IWDG_Handler; //獨(dú)立看門(mén)狗句柄
//初始化獨(dú)立看門(mén)狗
//prer:分頻數(shù):IWDG_PRESCALER_4~IWDG_PRESCALER_256
//rlr:自動(dòng)重裝載值,0~0XFFF.
//時(shí)間計(jì)算(大概):Tout=((4*2^prer)*rlr)/32 (ms).
void IWDG_Init(u8 prer,u16 rlr)
{
IWDG_Handler.Instance=IWDG;
IWDG_Handler.Init.Prescaler=prer;
//設(shè)置 IWDG 分頻系數(shù)
IWDG_Handler.Init.Reload=rlr;
//重裝載值
HAL_IWDG_Init(&IWDG_Handler); //初始化 IWDG,默認(rèn)會(huì)開(kāi)啟獨(dú)立看門(mén)狗
HAL_IWDG_Start(&IWDG_Handler); //啟動(dòng)獨(dú)立看門(mén)狗
}
//喂獨(dú)立看門(mén)狗
void IWDG_Feed(void)
{
HAL_IWDG_Refresh(&IWDG_Handler); //喂狗
}
該代碼就 2 個(gè)函數(shù),void IWDG_Init(u8 prer,u16 rlr)是獨(dú)立看門(mén)狗初始化函數(shù),就是按照
上面介紹的步驟 1 來(lái)初始化獨(dú)立看門(mén)狗的,并且啟動(dòng)。該函數(shù)有 2 個(gè)參數(shù),分別用來(lái)設(shè)置與預(yù)
分頻數(shù)與重裝寄存器的值的。通過(guò)這兩個(gè)參數(shù),就可以大概知道看門(mén)狗復(fù)位的時(shí)間周期為多少
了。其計(jì)算方式上面有詳細(xì)的介紹,這里不再多說(shuō)了。
void IWDG_Feed(void)函數(shù),該函數(shù)用來(lái)喂狗,因?yàn)?STM32F4 的喂狗只需要向鍵值寄存器
寫(xiě)入 0XAAAA 即可,也就是調(diào)用 IWDG_ReloadCounter()函數(shù),所以,我們這個(gè)函數(shù)也是簡(jiǎn)單的
很。
iwdg.h 內(nèi)容比較簡(jiǎn)單,主要是一些函數(shù)聲明,這里我們忽略不講解。
接下來(lái)我們看看主函數(shù) main 的代碼。在主程序里面我們先初始化一下系統(tǒng)代碼,然后啟動(dòng)
按鍵輸入和看門(mén)狗,在看門(mén)狗開(kāi)啟后馬上點(diǎn)亮 LED0(DS0),并進(jìn)入死循環(huán)等待按鍵的輸入,
一旦 KEY_UP 有按鍵,則喂狗,否則等待 IWDG 復(fù)位的到來(lái)。這段代碼很容易理解,該部分
代碼如下:
int main(void)
{
HAL_Init();
//初始化 HAL 庫(kù)
Stm32_Clock_Init(96,4,2,4); //設(shè)置時(shí)鐘,96Mhz
delay_init(96);
//初始化延時(shí)函數(shù)
uart_init(115200);
//初始化串口 115200
LED_Init();
//初始化 LED
KEY_Init();
//初始化按鍵
delay_ms(100);
//延時(shí) 100ms 再初始化看門(mén)狗,LED0 的變化"可見(jiàn)"
IWDG_Init(IWDG_PRESCALER_64,500); //分頻數(shù)為 64,重載值為 500,溢出時(shí)間為 1s
LED0=0;
while(1)
{
if(KEY_Scan(0)==WKUP_PRES) //如果 WK_UP 按下,喂狗
{
IWDG_Feed();
//喂狗
}
delay_ms(10);
}
}
上面的代碼,鑒于篇幅考慮,我們沒(méi)有把頭文件給列出來(lái)(后續(xù)實(shí)例將會(huì)采用類(lèi)同的方
式處理),因?yàn)橐院笪覀儼念^文件會(huì)越來(lái)越多,大家想看,可以直接打開(kāi)光盤(pán)相關(guān)源碼查
看。至此,獨(dú)立看門(mén)狗的實(shí)驗(yàn)代碼,我們就全部編寫(xiě)完了,接著要做的就是下載驗(yàn)證了,看看
我們的代碼是否真的正確。11.4 下載驗(yàn)證
在編譯成功之后,我們就可以下載代碼到 NANO STM32F4 開(kāi)發(fā)板上,實(shí)際驗(yàn)證一下,我
們的程序是否正確。下載代碼后,可以看到 DS0 不停的閃爍,證明程序在不停的復(fù)位,否則只
會(huì) DS0 常亮。這時(shí)我們?cè)囋嚥煌5陌?KEY_UP 按鍵,可以看到 DS0 就常亮了,不會(huì)再閃爍。
說(shuō)明我們的實(shí)驗(yàn)是成功的。11.5 STM32CubeMX 配置 IWDG
使用 STM32CubeMX 工具配置 IWDG 生成初始化代碼的步驟非常簡(jiǎn)單,我們只需要使能
IWDG,同時(shí)配置 IWDG 的預(yù)分頻系數(shù)和自動(dòng)裝載值即可。
首先我們看看使能 IWDG 的方法,在 System Core 界面的一欄選擇 IWDG,然后勾選上
Activated 選項(xiàng)即可使能 IWDG。操作方法如下圖 11.5.1:
圖 11.5.1 IWDG 配置選項(xiàng)
接下來(lái)依次點(diǎn)擊 Configuration->IWDG,進(jìn)入 IWDG 參數(shù)配置界面。進(jìn)入配置界面后,我
們依次配置 IWDG 的預(yù)分頻系數(shù)和自動(dòng)裝載值,這兩個(gè)參數(shù)的含義我們?cè)谇懊嬉呀?jīng)講解。
IWDG
Configuration 配置界面如下圖 11.5.2 所示:
圖 11.5.2 IWDG 參數(shù)配置界面
這里我們配置預(yù)分頻系數(shù)為 64,同時(shí)自動(dòng)裝載值為 500 即可。配置完成后生成實(shí)驗(yàn)工程。
在生成的工程中,打開(kāi) main 文件可以看到生成的函數(shù) MX_IWDG_Init 和看門(mén)狗實(shí)驗(yàn)工程中的
IWDG_Init 函數(shù)內(nèi)容一致,不同的是 IWDG_Init 函數(shù)的這兩個(gè)參數(shù)是通過(guò)入口參數(shù)傳入的。當(dāng)然,對(duì)于合適啟動(dòng)看門(mén)狗以及何時(shí)喂狗的操作軟件是無(wú)法確定的,還需要用戶(hù)根據(jù)自己需求在合適的程序段中編寫(xiě)這兩項(xiàng)操作。
總結(jié)
以上是生活随笔為你收集整理的stm32看门狗_「正点原子NANO STM32开发板资料连载」第十一章 独立看门狗实验的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: uml+oopc嵌入式c语言开发精讲_当
- 下一篇: python中self_一篇文章让你彻底