STM32第三章-系統時鐘配置

學習系統時鐘以前先問你們一個問題? 這是一個跑馬燈的程序,爲何咱們沒有在主函數中配置系統時鐘,卻能夠正常的執行流水燈代碼呢? 我想大多數人都會說,已經配置了系統時鐘,不須要在主函數中調用了。若是你回答不上來或者不清楚系統時鐘是怎樣配置的就好好看下文了。至此引出系統時鐘的概念安全

全部數字計算機系統都是由某種形式的震盪時鐘電路驅動的。這種電路被稱爲系統的「脈搏」,是系統正確運行的關鍵。若是振盪器失靈,系統將徹底沒法運行,若是振盪器運行不規律,系統執行的全部時間有關的計算都會有偏差。 全部微控制器的啓動流程都不通用。因爲硬件的複雜性,必須運行一段由廠家定義的短小的「復位程序」來使硬件處於一種正確的狀態,而後再開始執行用戶程序。運行這個復位程序須要時間而且要求微控制器的振盪器已經運行。 當系統由可靠的電源供電時,一旦通電,電源迅速地達到額定輸出電壓,一旦關電,電源迅速地降低到 0V,而且在接通的時候,電壓不會下降。這時可以可靠地使用基於一個電容和一個電阻的低成本硬件復位。這種形式的復位電路稱爲阻容復位。若是電源不夠可靠,而涉及安全性,這種簡單的阻容解決方案就不合適了。markdown

我這裏以STM32F429爲例,其餘的芯片的原理都是同樣的。函數

  • STM32F429主板上有兩個無源晶振第一個是主晶振,頻率爲8MHz,通過內部PLL倍頻到168MHz,做爲CPU內核的時鐘使用。第二個晶振頻率爲32.768kHz,用於內部RTC電路。第二個晶振不是必須的,當須要使用STM32內部RTC時鐘功能時才須要安裝32.768k晶振
  • CPU的內核時鐘能夠高達180MHz,但並非說咱們就必需要設置爲最高180MHZ。你能夠設置爲小於等於180MHZ均可以。可是CPU內部的外設,好比ADC,GPIO,部分TIM是達不到這麼高的速度的。CPU的時鐘管理電路有好幾個分頻器,不一樣速度的外設給定不一樣的時鐘。
  • 主時鐘選擇的是HSE高速外部時鐘。 系統時鐘 SYSCLK =PLLCLK= 168MHz AHB總線時鐘HCLK = SYSCLK=168MHz APB1外設時鐘PCLK1 = HCLK /4=42MHz APB2外設時鐘PCLK2 = HCLK /2=84MHz

時鐘樹單純講理論的話會比較枯燥,若是選取一條主線,並輔以代碼,先主後次講解的話會很容易,並且記憶還更深入。咱們這裏選取庫函數時鐘系統時鐘函數:SetSysClock();這個函數在system_stm32f4xx.c中,以這個函數的編寫流程來說解時鐘樹,這個函數也是咱們用庫的時候默認的系統時鐘設置函數。該函數的功能是利用HSE把時鐘設置爲: 系統時鐘 SYSCLK =PLLCLK= 168MHz AHB總線時鐘HCLK = SYSCLK=168MHz APB1外設時鐘PCLK1 = HCLK /4=42MHz APB2外設時鐘PCLK2 = HCLK /2=84MHz 有人會問F4不是主頻180MHZ,APB1=90MHZ,APB2=180MHZ嗎?確實你看到的大部分程序中F4都是這樣配置的,可是並不表明必須這樣配置,你能夠想配置多少就是多少。只要不超多系統最高時鐘的限制180MHZ。固然又會有人說了,不是能夠超頻嗎?是能夠超頻可是99%都不會超頻。性能

下面咱們來看時鐘樹:在這裏插入圖片描述 在 STM32F429 中,有 5 個最重要的時鐘源,按照上圖的順序爲LSI、LSE、 HSE、HSL、PLL。H開頭的是高速時鐘、L開頭的是低速時鐘。其中 PLL分爲三個時鐘源,分別爲主 PLL 和 I2S 部分專用 PLLI2S 和 SAI 部分專用 PLLSAI。其中 HSE 和 LSE 是外部時鐘源就是從外部經過接晶振的方式獲取時鐘源(就是須要外界晶振),其餘的是內部時鐘源(不須要外接晶振)。下面咱們看看 STM32F429 的這 5 個時鐘源,咱們講解順序是按圖中紅圈標示的順序:學習

  • ①LSI 是低速內部時鐘,RC 振盪器,頻率爲 32kHz 左右。供獨立看門狗和自動喚醒單元使用。
  • ②LSE 是低速外部時鐘,接頻率爲 32.768kHz 的石英晶體。這個主要是 RTC 的時鐘源
  • ③HSE是高速外部時鐘,可接石英/陶瓷諧振器,或者接外部時鐘源,頻率範圍爲 4MHz~26MHz。當使用有源晶振時,時鐘從 OSC_IN 引腳進入,OSC_OUT 引腳懸空,當選用無源晶振時,時鐘從 OSC_IN 和 OSC_OUT進入,而且要配諧振電容。HSE 咱們使用 8M的無源晶振。若是咱們使用 HSE或者 HSE通過 PLL倍頻以後的時鐘做爲系統時鐘 SYSCLK。野火和正點原子的F429開發板接的是 25M 的晶振安富萊的開發板是8M外接晶振。HSE 也能夠直接作爲系統時鐘或者 PLL 輸入。
  • ④HSI 是高速內部時鐘,RC 振盪器,頻率爲 16MHz。能夠直接做爲系統時鐘或者用做 PLL輸入。
  • ⑤PLL 爲鎖相環倍頻輸出。STM32F4 有三個 PLL: 主 PLL(PLL)由 HSE 或者 HSI 提供時鐘信號,並具備兩個不一樣的輸出時鐘。 第一個專用 PLL(PLLI2S)用於生成精確時鐘,在 I2S 和 SAI1 上實現高品質音頻性能。(不多用先不看) 第二個專用 PLL(PLLSAI)一樣用於生成精確時鐘,用於 SAI1 輸入時鐘。(不多用先不看) 這裏咱們着重看看主 PLL 時鐘第一個高速時鐘輸出 PLLP 的計算方法。是主 PLL 的時鐘圖。 主 PLL 的時鐘圖

主 PLL 時鐘的時鐘源要先通過一個分頻係數爲 M 的分頻器,而後通過倍頻係數爲 N 的倍頻器出來以後還須要通過一個分頻係數爲 P(第一個輸出 PLLP)或者 Q(第二個輸出 PLLQ)的分頻器分頻以後,最後才生成最終的主 PLL 時鐘。例如咱們的外部晶振選擇 8MHz。同時咱們設置相應的分頻器 M=8,倍頻器倍頻係數 N=336,分頻器分頻係數 P=2,那麼主 PLL 生成的第一個輸出高速時鐘 PLLP 爲:8MHZ/8*336/2=168ui

PLL=8MHz * N/ (M*P)=8MHz* 336 /(8*2) = 168MHz
複製代碼

若是咱們選擇HSE爲PLL時鐘源,同時SYSCLK時鐘源爲PLL,那麼SYSCLK時鐘爲 168MHz。 看下面的程序也是這樣的,說明計算無誤。 spa

助記:由於2大於1,隨因此APB2外設時鐘也必定要大於APB2外設時鐘。code

具體的實現請看下圖: 單純地講解系統的時鐘框圖的,請看具體的數據手冊,咱們這裏只是簡單的介紹這個系統時鐘是怎麼來的。好比告訴你,我如今的外接晶振是25M。可是我想要配置成系統時鐘是180MHZ的你會嗎?你會本身去配置嗎? 看到這裏我想你已經會配置了。好比我這設置PLL_M=25,PLL_N=360,PLL_P=2。那麼個人系統時鐘SYSCLK就是:orm

PLL=25MHz * N/ (M*P)=25MHz* 330 /(25*2) = 180MHz。
複製代碼

若是咱們選擇HSE爲PLL時鐘源,同時SYSCLK時鐘源爲PLL,那麼SYSCLK時鐘爲 180MHz。圖片

  • HCLK=SYSCLK=PLLCLK=180M,只須要設置AHB Prescaler分頻因子爲1就能夠了。
  • PCLK1=HCLK/2=90M,只須要設置AHB1 Prescaler分頻因子爲2就能夠了。
  • PCLK2=HCLK=180M。只須要設置AHB2 Prescaler分頻因子爲1就能夠了。

代碼分析

至此咱們已經大概的瞭解到了系統時鐘是怎麼一回事。如今咱們來分析具體的代碼。否則值分析沒代碼,學起來效果很差。 還記得我在前面我提到的問題嗎? 其實在按下單片機上面的復位按鍵以後。根據我麼上一篇文章說的。系統會這些首先執行啓動代碼的裏面的程序。 咱們打開startup_stm32f429_439xx.s文件。固然我這裏以F4爲例,其餘的也都是同樣的。會看到在系統復位時候在執行main函數以前先執行了SystemInit函數。那咱們如今看看SystemInit函數中都有啥。鼠標放在SystemInit函數上面右鍵選擇Go To Defintion of SystemInit 就會跳轉到system_stm32f4xx.c文件中的SystemInit函數上來了。下面來一行一行分析: 第592行:RCC->CR |= (uint32_t)0x00000001;配置RCC寄存器的時鐘控制RCC_CR寄存器第0位爲1。打開HSI振盪器。 第595行:RCC->CFGR = 0x00000000;復位RCC寄存器的時鐘配置CFGR寄存器,全爲0。 第598行:RCC->CR &= (uint32_t)0xFEF6FFFF;;復位RCC寄存器的時鐘控制CR寄存器的HSEON、CSSON、PLLON爲0。 第601行:RCC->PLLCFGR = 0x24003010;復位RCC寄存器的配置PLLCFGR寄存器。具體的操做能夠看下面對應的寄存器位值。 第604行:RCC->CR &= (uint32_t)0xFFFBFFFF;復位RCC寄存器的CR寄存器。 第604行:RCC->CIR = 0x00000000;失能RCC寄存器的CIR寄存器,關閉全部中斷。這兩行就不一一列舉了。 第615行:SetSysClock()這個函數主要是配置AHB、AHB一、AHB2的時鐘頻率。 到這裏系統時鐘就所有配置完成了。在這兩個函數中有不少的宏定義,在看代碼的時候必定要注意是操做了哪一位,在對應爲去找STM32fx的中文參考手冊就容易理解多了。

要會看宏定義: #define RCC_CR_HSEON ((uint32_t)0x00010000) 0x0001 0000。 就是把RCC寄存器的CR寄存器的HSEON置位1。根據 0x0001 0000能夠知道HSEON處於CR寄存器的第16位,這一點很重要。

最後來一個總結,在咱們按下開發板上面的復位按鍵以後,系統從啓動文件中先執行SystemInit函數,在SystemInit函數中配置了PLL鎖相環的各個分頻因子,獲得了系統時鐘。在SystemInit函數中又調用了SetSysClock()函數,來配置AHB、AHB一、AHB2的時鐘頻率。

如今咱們系統時鐘配置你會了嗎?須要注意的是,咱們寫在程序的時候通常不須要配置時鐘,由於咱們通常用的是被人寫好的工程模板,直接拿來用就能夠了。可是仍是須要了解,時鐘樹的知識比較難以理解,相信你們看上面的內容都會配置了吧!

相關文章
相關標籤/搜索