tft每日頭條

 > 寵物

 > stm32電子時鐘設計

stm32電子時鐘設計

寵物 更新时间:2024-11-24 19:57:24

1)實驗平台:正點原子STM32mini開發闆2)摘自《正點原子STM32 不完全手冊(HAL 庫版)關注官方微信号公衆号,獲取更多資料:正點原子

stm32電子時鐘設計(正點原子STM32Mini闆資料連載)1

第十章 獨立看門狗(IWDG)實驗

這一章,我們将向大家介紹如何使用 STM32 的獨立看門狗(以下簡稱 IWDG)。STM32 内

部自帶了 2 個看門狗:獨立看門狗(IWDG)和窗口看門狗(WWDG)。這一章我們隻介紹獨

立看門狗,窗口看門狗将在下一章介紹。在本章中,我們将通過按鍵 WK_UP 來喂狗,然後通

過 DS0 提示複位狀态。本章分為如下幾個部分:

10.1 STM32 獨立看門狗簡介

10.2 硬件設計

10.3 軟件設計

10.4 下載驗證

10.1 STM32 獨立看門狗簡介

STM32 的獨立看門狗由内部專門的 40Khz 低速時鐘驅動,即使主時鐘發生故障,它也仍然

有效。這裡需要注意獨立看門狗的時鐘是一個内部 RC 時鐘,所以并不是準确的 40Khz,而是

在 30~60Khz 之間的一個可變化的時鐘,隻是我們在估算的時候,以 40Khz 的頻率來計算,看

門狗對時間的要求不是很精确,所以,時鐘有些偏差,都是可以接受的。

獨立看門狗有幾個寄存器與我們這節相關,我們分别介紹這幾個寄存器,首先是鍵值寄存

器 IWDG_KR,該寄存器的各位描述如圖 10.1.1 所示:

stm32電子時鐘設計(正點原子STM32Mini闆資料連載)2

圖 10.1.1 IWDG_KR 寄存器各位描述

在鍵寄存器(IWDG_KR)中寫入 0xCCCC,開始啟用獨立看門狗;此時計數器開始從其複位

值 0xFFF 遞減計數。當計數器計數到末尾 0x000 時,會産生一個複位信号(IWDG_RESET)。 無

論何時,隻要鍵寄存器 IWDG_KR 中被寫入 0xAAAA, IWDG_RLR 中的值就會被重新加載到

計數器中從而避免産生看門狗複位 。

IWDG_PR 和 IWDG_RLR 寄存器具有寫保護功能。要修改這兩個寄存器的值,必須先向

IWDG_KR 寄存器中寫入 0x5555。将其他值寫入這個寄存器将會打亂操作順序,寄存器将重新

被保護。重裝載操作(即寫入 0xAAAA)也會啟動寫保護功能。

接下來,我們介紹預分頻寄存器(IWDG_PR),該寄存器用來設置看門狗時鐘的分頻系數,

最低為 4,最高位 256,該寄存器是一個 32 位的寄存器,但是我們隻用了最低 3 位,其他都是

保留位。預分頻寄存器各位定義如圖 10.1.2 所示:

stm32電子時鐘設計(正點原子STM32Mini闆資料連載)3

圖 10.1.2 IWDG_ PR 寄存器各位描述

在介紹完 IWDG_PR 之後,我們介紹一下重裝載寄存器。該寄存器用來保存重裝載到計數

器中的值。該寄存器也是一個 32 位寄存器,但是隻有低 12 位是有效的,該寄存器的各位描述

如圖 10.1.3 所示:

stm32電子時鐘設計(正點原子STM32Mini闆資料連載)4

圖 10.1.3 重裝載寄存器各位描述

隻要對以上三個寄存器進行相應的設置,我們就可以啟動 STM32F1 的獨立看門狗。獨立

看 門 狗 相 關 的 庫 函 數 操 作 函 數 在 文 件 stm32f1xx_hal_iwdg.c 和 對 應 的 頭 文 件

stm32f1xx_hal_iwdg.h 中。

接下來我們講解一下通過庫函數來配置獨立看門狗的步驟:

1)取消寄存器寫保護(向 IWDG_KR 寫入 0X5555)

首先我們必須取消 IWDG_PR 和 IWDG_RLR 寄存器的寫保護,這樣才可以設置寄存器

IWDG_PR 和 IWDG_RLR 的值。取消寫保護和設置預分頻系數以及重裝載值在 HAL 庫中是通

過函數 HAL_IWDG_Init 實現的。該函數聲明為:

HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg);

該函數隻有一個入口參數 hiwdg,該參數是 IWDG_HandleTypeDef 結構體指針類型。接下

來我們看看結構體 IWDG_HandleTypeDef 定義:

typedef struct

{

IWDG_TypeDef *Instance;

IWDG_InitTypeDef Init;

}IWDG_HandleTypeDef;

成員變量 Instance 用來設置看門狗寄存器基地址,實際上在 HAL 庫中已經通過标識符定義

了,這裡對于獨立看門狗直接設置為标識符 IWDG 即可。

成員變量 Init 是一個 IWDG_InitTypeDef 結構體類型,該結構體隻有 2 個成員變量,分别用

來設置獨立看門狗的預分頻系數和重裝載值,定義如下:

typedef struct

{

uint32_t Prescaler;

uint32_t Reload;

}IWDG_InitTypeDef;

成員變量 Lock 是一個鎖存變量,該變量在 HAL 庫中當操作配置 IWDG 之前設置為鎖住

LOCK,當配置操作完成之後設置為 UNLOCK,實際上是一個操作狀态标識符。

成員變量 State 也是 HAL 定義的一個過程标識符,用來記錄 IWDG 處理狀态。

HAL_IWDG_Init 函數使用的一般方法為:

IWDG_HandleTypeDef IWDG_Handler; //獨立看門狗句柄

IWDG_Handler.Instance=IWDG;

//獨立看門狗

IWDG_Handler.Init.Prescaler=IWDG_PRESCALER_64; //設置 IWDG 分頻系數

IWDG_Handler.Init.Reload=500; //重裝載值

HAL_IWDG_Init(&IWDG_Handler);

上面程序的作用是初始化 IWDG,設置分頻系數為 64,重裝載值為 500。設置完預分頻系

數和重裝載值後,我們就可以知道看門狗的喂狗時間(也就是看門狗溢出時間),該時間的計算

方式為:

Tout=((4×2^prer) ×rlr) /32

其中 Tout 為看門狗溢出時間(單位為 ms);prer 為看門狗時鐘預分頻值(IWDG_PR 值),

範圍為 0~7;rlr 為看門狗的重裝載值(IWDG_RLR 的值);

比如我們設定 prer 值為 4(4 代表的是 64 分頻,HAL 庫中可以使用宏定義标識符

IWDG_PRESCALER_64),rlr 值為 500,那麼就可以得到 Tout=64×500/32=1000ms,這樣,看

門狗的溢出時間就是 1s,隻要你在一秒鐘之内,有一次寫入 0XAAAA 到 IWDG_KR,就不會

導緻看門狗複位(當然寫入多次也是可以的)。這裡需要提醒大家的是,看門狗的時鐘不是準确

的 32Khz,所以在喂狗的時候,最好不要太晚了,否則,有可能發生看門狗複位。

2)重載計數值喂狗(向 IWDG_KR 寫入 0XAAAA)

在 HAL 中重載計數值的函數是 HAL_IWDG_Refresh,該函數聲明為:

HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg);

該函數有一個入口參數為前面講解的 IWDG_HandleTypeDef 結構體類型指針,它的作用是

把值0xAAAA寫入到IWDG_KR寄存器,從而觸發計數器重載,即實現獨立看門狗的喂狗操作。

3) 啟動看門狗(向 IWDG_KR 寫入 0XCCCC)

HAL 庫函數裡面啟動獨立看門狗的函數是__HAL_IWDG_START:

__HAL_IWDG_START(hiwdg);

通過上面 3 個步驟,我們就可以啟動 STM32F1 的獨立看門狗了,使能了看門狗,在程序

裡面就必須間隔一定時間喂狗,否則将導緻程序複位。利用這一點,我們本章将通過一個 LED

燈來指示程序是否重啟,來驗證 STM32F1 的獨立看門狗。

在配置看門狗後,DS0 将常亮,如果 KEY_UP 按鍵按下,就喂狗,隻要 KEY_UP 不停的

按,看門狗就一直不會産生複位,保持 DS0 的常亮,一旦超過看門狗定溢出時間(Tout)還沒

按,那麼将會導緻程序重啟,這将導緻 DS0 熄滅一次。

10.2 硬件設計

本實驗用到的硬件資源有:

1) 指示燈 DS0

2) WK_UP 按鍵

3) 獨立看門狗

前面兩個在之前都有介紹,而獨立看門狗實驗的核心是在 STM32 内部進行,并不需要外

部電路。但是考慮到指示當前狀态和喂狗等操作,我們需要 2 個 IO 口,一個用來輸入喂狗信

号,另外一個用來指示程序是否重啟。喂狗我們采用闆上的 WK_UP 鍵來操作,而程序重啟,則是通過 DS0 來指示的。

10.3 軟件設計

軟件設計我們依舊是在上一章代碼的基礎上修改,因為沒用到外部中斷,所以先去掉 exti.c

(注意,此時 HARDWARE 組僅剩:led.c 和 key.c),然後在 HARDWARE 文件夾下面新建一個

WDG 的文件夾,用來保存與看門狗相關的代碼。再打開工程,新建 wdg.c 和 wdg.h 兩個文件,

并保存在 WDG 文件夾下,并将 WDG 文件夾加入頭文件包含路徑。

在 wdg.c 裡面輸入如下代碼:

#include "wdg.h"

IWDG_HandleTypeDef IWDG_Handler; //獨立看門狗句柄

//初始化獨立看門狗

//prer:分頻數:IWDG_PRESCALER_4~IWDG_PRESCALER_256

//rlr:自動重裝載值,0~0XFFF.

//時間計算(大概):Tout=((4*2^prer)*rlr)/32 (ms).

void IWDG_Init(u8 prer,u16 rlr)

{

IWDG_Handler.Instance=IWDG;

IWDG_Handler.Init.Prescaler=prer;

//設置 IWDG 分頻系數

IWDG_Handler.Init.Reload=rlr;

//重裝載值

HAL_IWDG_Init(&IWDG_Handler);

//初始化 IWDG,默認會開啟獨立看門狗

}

//喂獨立看門狗

void IWDG_Feed(void)

{

HAL_IWDG_Refresh(&IWDG_Handler); //喂狗

}

該代碼就 2 個函數,void IWDG_Init(u8 prer,u16 rlr)是獨立看門狗初始化函數,就是按照

上面介紹的步驟來初始化獨立看門狗的。該函數有 2 個參數,分别用來設置與預分頻數與重裝

寄存器的值的。通過這兩個參數,就可以大概知道看門狗複位的時間周期為多少了。其計算方

式上面有詳細的介紹,這裡不再多說了。

void IWDG_Feed(void)函數,該函數用來喂狗,因為 STM32 的喂狗隻需要向關鍵字寄存器

寫入 0XAAAA 即可,也就是調用庫函數 HAL_IWDG_Refresh,所以這個函數也是很簡單的。

iwdg.h 内容比較簡單,主要是一些函數申明,這裡我們忽略不講解。

接下來我們看看主函數,主程序裡面我們先初始化一下系統代碼,然後啟動按鍵輸入和看

門狗,在看門狗開啟後馬上點亮 LED0(DS0),并進入死循環等待按鍵的輸入,一旦 KEY_UP

有按鍵,則喂狗,否則等待 IWDG 複位的到來。該部分代碼如下:

int main(void)

{

HAL_Init(); //初始化 HAL 庫

Stm32_Clock_Init(RCC_PLL_MUL9); //設置時鐘,72M

delay_init(72);

//初始化延時函數

uart_init(115200);

//初始化串口

LED_Init();

//初始化 LED

KEY_Init();

//初始化按鍵

delay_ms(100); //延時 100ms 再初始化看門狗,LED0 的變化"可見"

IWDG_Init(IWDG_PRESCALER_64,500);//分頻數為 64,重載值為 500,溢出時間為 1s

LED0=0;

while(1)

{

if(KEY_Scan(0)==WKUP_PRES) //如果 WK_UP 按下,喂狗

{

IWDG_Feed();

//喂狗

}

delay_ms(10);

}

}

上面的代碼,鑒于篇幅考慮,我們沒有把頭文件給列出來(後續實例将會采用類同的方式

處理),因為以後我們包含的頭文件會越來越多,大家想看,可以直接打開光盤相關源碼查看。

至此,獨立看門狗的實驗代碼,我們就全部編寫完了,接着要做的就是下載驗證了,看看我們

的代碼是否真的正确。

10.4 下載驗證

在編譯成功之後,我們就可以下載代碼到 MiniSTM32 開發闆上,實際驗證一下,我們的程

序是否正确。下載代碼後,可以看到 DS0 不停的閃爍,證明程序在不停的複位,否則隻會 DS0

常亮。這時我們試試不停的按 WK_UP 按鍵,可以看到 DS0 就常亮了,不會再閃爍。說明我們

的實驗是成功的

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关寵物资讯推荐

热门寵物资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved