stm32f107內部時鐘設置(STM32F103開發板資料連載)
2023-05-23 01:03:20
1)實驗平臺:【正點原子】 NANO STM32F103 開發板
2)摘自《正點原子STM32 F1 開發指南(NANO 板-HAL 庫版)》關注官方微信號公眾號,獲取更多資料:正點原子
第十一章 獨立看門狗(IWDG)實驗
這一章,我們將向大家介紹如何使用 STM32 的獨立看門狗(以下簡稱 IWDG)。STM32內部自帶了 2 個看門狗:獨立看門狗(IWDG)和窗口看門狗(WWDG)。這一章我們只介紹獨立看門狗,窗口看門狗將在下一章介紹。在本章中,我們將通過按鍵 KEY_UP 來餵狗,然後通過 DS0 提示復位狀態。本章分為如下幾個部分:
11.1 STM32 獨立看門狗簡介
11.2 硬體設計
11.3 軟體設計
11.4 11.1 STM32 獨立看門狗簡介
STM32 的獨立看門狗由內部專門的 40Khz 低速時鐘驅動,即使主時鐘發生故障,它也仍然有效。這裡需要注意獨立看門狗的時鐘是一個內部 RC 時鐘,所以並不是準確的 40Khz,而是在 30~60Khz 之間的一個可變化的時鐘,只是我們在估算的時候,以 40Khz 的頻率來計算,看門狗對時間的要求不是很精確,所以,時鐘有些偏差,都是可以接受的。首先我們得講解一下看門狗的原理。這個百度百科裡面有很詳細的解釋。我們總結一下:單片機系統在外界的幹擾下會出現程序跑飛的現象導致出現死循環,看門狗電路就是為了避免這種情況的發生。看門狗的作用就是在一定時間內(通過定時計數器實現)沒有接收餵狗信號(表示 MCU 已經掛了),便實現處理器的自動復位重啟(發送復位信號)。下面我們在了解幾個與獨立看門狗相關聯的寄存器之後講解怎麼通過庫函數來實現配置。首先是鍵值寄存器 IWDG_KR,該寄存器的各位描述如圖 11.1.1 所示:下載驗證
11.5 STM32CubeMX 配置 IWDG
圖 11.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),該寄存器用來設置看門狗時鐘的分頻
係數。另一個重裝載寄存器。該寄存器用來保存重裝載到計數器中的值。該寄存器也是一個 32
位寄存器,但是只有低 12 位是有效的。
只要對以上三個寄存器進行相應的設置,我們就可以啟動 STM32 的獨立看門狗,獨立看
門狗相關的 HAL 庫操作函數在文件 stm32f1xx_hal_iwdog.c 和頭文件 stm32f1xx_hal_iwdg.h 中。
接下來我們講解一下通過 HAL 庫配置獨立看門狗的步驟:
1)取消寄存器防寫,設置看門狗預分頻係數和重裝載值,並啟動看門狗
首先我們必須取消 IWDOG_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;
HAL_IWDG_Init 函數使用的一般方法為:
IWDG_HandleTypeDef IWDG_Handler; //獨立看門狗句柄
IWDG_Handler.Instance=IWDG; //獨立看門狗
IWDG_Handler.Init.Prescaler=IWDG_PRESCALER_64; //設置 IWDG 分頻係數
IWDG_Handler.Init.Reload=625;
//重裝載值
HAL_IWDG_Init(&IWDG_Handler); //初始化 IWDG,默認會開啟獨立看門狗
上面程序的作用是初始化 IWDG,設置分頻係數為 64,重裝載值為 500。設置完預分頻系
數和重裝載值後,我們就可以知道看門狗的餵狗時間(也就是看門狗溢出時間),該時間的計
算方式為:
Tout=((4×2^prer) ×rlr) /40
其中 Tout 為看門狗溢出時間(單位為 ms);prer 為看門狗時鐘預分頻值(IWDG_PR 值),
範圍為 0~7;rlr 為看門狗的重裝載值(IWDG_RLR 的值);
比如我們設定 prer 值為 4(4 代表的是 64 分頻,HAL 庫中可以使用宏定義標識符
IWDG_PRESCALER_64),rlr 值為 625,那麼就可以得到 Tout=64×625/40=1000ms,這樣,看
門狗的溢出時間就是 1s,只要你在一秒鐘之內,有一次寫入 0XAAAA 到 IWDG_KR,就不會
導致看門狗復位(當然寫入多次也是可以的)。這裡需要提醒大家的是,看門狗的時鐘不是準
確的 40Khz,所以在餵狗的時候,最好不要太晚了,否則,有可能發生看門狗復位。
內部初始化 IWDG 後,同時會啟動看門狗(IWDG_KR 寫入 0XCCCC)。
2)重載計數值餵狗(向 IWDG_KR 寫入 0XAAAA)
在 HAL 中重載計數值函數是 HAL_IWDG_Refresh,該函數聲明為:
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg);
該函數有一個入口參數為前面所講的 IWDG_HandleTypeDef 結構體類型指針,它的作用是
把值 0xAAAA 寫入到 IWDG_KR 寄存器,從而觸發計數器重載,及實現獨立看門狗的餵狗操作。
通過上面的步驟,我們就可以啟動 STM32 的看門狗了,使能了看門狗,在程序裡面就必
須間隔一定時間餵狗,否則將導致程序復位。利用這一點,我們本章將通過一個 LED 燈來指示
程序是否重啟,來驗證 STM32 的獨立看門狗。
在配置看門狗後,DS0 將常亮,如果 KEY_UP 按鍵按下,就餵狗,只要 KEY_UP 不停的
按,看門狗就一直不會產生復位,保持 DS0 的常亮,一旦超過看門狗定溢出時間(Tout)還沒
按,那麼將會導致程序重啟,這將導致 DS0 熄滅一次。
11.2 硬體設計
本實驗用到的硬體資源有:
1) 指示燈 DS0
2) WK_UP 按鍵
3) 獨立看門狗
前面兩個在之前都有介紹,而獨立看門狗實驗的核心是在 STM32 內部進行,並不需要外
部電路。但是考慮到指示當前狀態和餵狗等操作,我們需要 2 個 IO 口,一個用來輸入餵狗信
號,另外一個用來指示程序是否重啟。餵狗我們採用板上的 KEY_UP 鍵來操作,而程序重啟,
則是通過 DS0 來指示的。
11.3 軟體設計
我們直接打開光碟的獨立看門狗實驗工程,可以看到工程裡面新增了 iwdg.c,同時引入了
頭文件 iwdg.h。同樣的道理,我們要加入 HAL 庫看門狗支持文件 stm32f1xx_hal_iwdg.h 和
stm32f1xx_hal_iwdg.c 文件。
iwdg.c 裡面的代碼如下:
#include "iwdg.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)是獨立看門狗初始化函數,就是按照
上面介紹的步驟 1 來初始化獨立看門狗的,並且啟動。該函數有 2 個參數,分別用來設置與預
分頻數與重裝寄存器的值的。通過這兩個參數,就可以大概知道看門狗復位的時間周期為多少
了。其計算方式上面有詳細的介紹,這裡不再多說了。
void IWDG_Feed(void)函數,該函數用來餵狗,因為 STM32 的餵狗只需要向鍵值寄存器寫
入 0XAAAA 即可,也就是調用 IWDG_ReloadCounter函數,所以,我們這個函數也是簡單的很。
iwdg.h 內容比較簡單,主要是一些函數聲明,這裡我們忽略不講解。
接下來我們看看主函數 main 的代碼。在主程序裡面我們先初始化一下系統代碼,然後啟動
按鍵輸入和看門狗,在看門狗開啟後馬山點亮 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,625); //分頻數為 64,重載值為 625,溢出時間為 1s
LED0=0;
while(1)
{
if(KEY_Scan(0)==WKUP_PRES) //如果 WK_UP 按下,餵狗
{
IWDG_Feed; //餵狗
}
delay_ms(10);
}
}
上面的代碼,鑑於篇幅考慮,我們沒有把頭文件給列出來(後續實例將會採用類同的方
式處理),因為以後我們包含的頭文件會越來越多,大家想看,可以直接打開光碟相關源碼查
看。至此,獨立看門狗的實驗代碼,我們就全部編寫完了,接著要做的就是下載驗證了,看看
我們的代碼是否真的正確,當然在下載之前可以通過軟體仿真看看是否可行。
11.4 下載驗證
在編譯成功之後,我們就可以下載代碼到 NANO STM32 開發板上,實際驗證一下,我們
的程序是否正確。下載代碼後,可以看到 DS0 不停的閃爍,證明程序在不停的復位,否則只會
DS0 常亮。這時我們試試不停的按 KEY_UP 按鍵,可以看到 DS0 就常亮了,不會再閃爍。說
明我們的實驗是成功的。
11.5 STM32CubeMX 配置 IWDG
使用 STM32CubeMX 工具配置 IWDG 生成初始化代碼的步驟非常簡單,我們只需要使能
IWDG,同時配置 IWDG 的預分頻係數和自動裝載值即可。
首先我們看看使能 IWDG 的方法,在 Pinout 界面的 Peripherals 一欄選擇 IWDG,然後勾選
上 Activated 選項即可使能 IWDG。操作方法如下圖 11.5.1:
圖 11.5.1 IWDG 配置選項
接下來依次點擊 Configuration->IWDG,進入 IWDG 參數配置界面。進入配置界面後,我
們依次配置 IWDG 的預分頻係數和自動裝載值,這兩個參數的含義我們在前面已經講解。IWDG
Configuration 配置界面如下圖 11.5.2 所示:
圖 11.5.2 IWDG 參數配置界面
這裡我們配置預分頻係數為 64,同時自動裝載值為 625 即可。配置完成後生成實驗工程。在生成的工程中,打開 main 文件可以看到生成的函數 MX_IWDG_Init 和看門狗實驗工程中的
IWDG_Init 函數內容一致,不同的是 IWDG_Init 函數的這兩個參數是通過入口參數傳入的。當
然,對於合適啟動看門狗以及何時餵狗的操作軟體是無法確定的,還需要用戶根據自己需求在
合適的程序段中編寫這兩項操作。
,