時鐘樹:MCU 的總動脈
這兩天Inav 6 的移植已經(jīng)和 @Apple樹下? 把inav 的主要功能調(diào)測通過,基本的spi、i2c、uart、pwm、dshot 等功能已經(jīng)調(diào)測通過,后面就主要是完善功能。ATbetaflight的兩個主要的bug也都已經(jīng)修復(fù)完畢,回頭另行總結(jié)。有點時間繼續(xù)寫bf 的專欄。
今天這一章講Mcu的 時鐘樹,涉及一下幾個點:
1、為什么要用時鐘樹,at32 的時鐘樹與STM 32 的時鐘樹有哪些異同
2、PLL 的計算 時鐘頻率、總線、分頻,時鐘配置工具
3、內(nèi)外部時鐘源的選擇
4、bf 的時鐘樹初始化配置過程
????先說MCU 的時鐘樹,為什么C51 沒有這么復(fù)雜的時鐘樹,就確定一個主頻就可以工作的很好,而MCU我在用任何外設(shè)的時候都要時時刻刻的關(guān)心時鐘? 其實這是一個功耗與性能的妥協(xié)。 MCU在不同的應(yīng)用場景下,并不是頻率越高性能越好就越好。MCU 的工作狀態(tài)要隨著場景變化的需要來決定自己的性能,必須時刻平衡整體設(shè)備的功耗與性能,尤其是使用電池供電的場景,如果需要達到較長的電池壽命,必須根據(jù)應(yīng)用的場景調(diào)整自己的工作模式。 舉個例子,我們的手機,在打游戲的時候這時候電池消耗不是問題,關(guān)鍵是要性能好不卡頓,這時候需要調(diào)整工作頻率到最高頻率,而我們晚上睡覺之后,手機扔一遍不能一直最高頻率運行,這時候就要進入到休眠模式,降低cpu和各個設(shè)備的工作頻率,關(guān)閉不需要的外設(shè)如屏幕、wifi、藍牙甚至基帶也會進入到低功耗的模式,然后定時器、看門狗又會定時的喚醒設(shè)備從休眠模式到低功耗模式。
MCU 也一樣,一個好的設(shè)計一定是考慮了各種場景的應(yīng)用。所以MCU 在設(shè)計之初,就把各個外設(shè)都設(shè)計為可以開關(guān)的、頻率可調(diào)的。
另外不管MCU 內(nèi)部的外設(shè),如GPIO 、定時器等,還是MCU 的通過各種接口,如SPI、I2S 等,外接的外設(shè),如果要正常工作,都必須在設(shè)計的頻率下通過MCU 的時鐘輸出來保證工作在同一個節(jié)拍下,驅(qū)動外設(shè)正常的工作,所以mcu 的外設(shè)時鐘樹是所有外設(shè)工作的前提, 要想功能正常,必須時刻知道外設(shè)工作在那個頻率上。我們做嵌入式相關(guān)的開發(fā), 所有外設(shè)的基本使用模式都是:
使能外設(shè)時鐘-》配置外設(shè)-》初始化外設(shè)-》使能外設(shè)-》失能外設(shè)-》關(guān)閉外設(shè)時鐘
在不同的模式之間切換的時候要針對不同場景的需求,重新啟用、使能、配置外設(shè)。
1、了解了為什么需要配置外設(shè)時鐘樹,我們來看下at32的時鐘樹與stm32f4 的時鐘樹異同 :

可以看到,二者時鐘樹基本大同小異,
同:
????都提供了內(nèi)部RC 高低速晶振、外部高低速晶振頻率源
????都提供了PLL 鎖相環(huán)
????都提供了usb 48M emac 頻率以及頻率輸出功能
???? 定時器的頻率都是在 ahb 總線 1分頻情況下 與ahb總線相同,2分頻情況下timer 頻率自動*2 的設(shè)置
不同:
????? stm32 針對 i2s 等頻率敏感的外設(shè)提供了第二套PLL
????? stm32 主頻比較低,但是APB總線頻率高(168m zh), AT32 主頻比較高,但是APB 總線頻率相對低(144Mhz),二者不構(gòu)成優(yōu)缺點,外設(shè)基本都不會需要這么高的頻率。
???? 二者的系統(tǒng)架構(gòu)不同,比如at32 的gpio 直接在ahb總線上,而STM32 是在apb1總線上,STM32 的APB總線區(qū)分高頻、低頻兩個總線,AT32 的兩個APB總線頻率一樣
????stm32 的外部時鐘源更寬泛一些, 支持4-27mzh? at32 支持4-26 mhz
????
其他:
????stm32 時鐘選擇更為復(fù)雜,相應(yīng)也可以更精確的控制系統(tǒng)功耗,
????二者都具備 時鐘校準、外部高速時鐘監(jiān)控的功能,在外部時鐘源失效的情況下產(chǎn)生中斷,這時可以切換系統(tǒng)時鐘源到內(nèi)部時鐘源避免系統(tǒng)直接死機。
????
2、PLL? 與時鐘配置工具
????PLL 的基礎(chǔ)知識不講,重點關(guān)注Sclk 的計算
二者? ????????????????????????????PLL 輸入時鐘 x PLL 倍頻系數(shù) N
???都是 Sclk =????? ------------------------------------------------------------------
????????????????????? ????????????(PLL 預(yù)分頻系數(shù) m x PLL 后分頻系數(shù) R)
比如選擇外部晶振 8M 輸入的情況下,配置 倍頻系數(shù) N= 72 預(yù)分頻系數(shù)m= 1 , 后分頻系數(shù) r=2
在at32 的時鐘配置工具界面可以通過選擇不同的開關(guān)、分頻系數(shù),來配置整個系統(tǒng)時鐘樹的時鐘,當然如果有多個工作模式的情況下,可以配置多套時鐘樹配置參數(shù),并自動按照對應(yīng)的芯片來生成代碼。
而 stm32 提供了更加強大的cubemx 工具進行時鐘樹的配置,由于主要目的是移植到at32 ,所以不做詳細的介紹。

Sclk= 8*72/1/2= 288Mhz
AHB= 288mhz
apb1= 288mhz/2 = 144mhz
apb2= 288mhz/2 = 144mhz
USB= 288/6? = 48Mhz
由于移植的飛控我們追求的是極致的性能,并不關(guān)注整體系統(tǒng)的功耗(相對電機的數(shù)百瓦的功耗,MCU 的功耗微乎其微),因此我們在設(shè)計之初就講at32f435/7 的整體系統(tǒng)頻率配置到最高。
3、內(nèi)外部時鐘源的選擇
芯片在內(nèi)部設(shè)計了高速、低速兩個時鐘源,同時也支持外部晶振作為時鐘源(32.khz , 8Mhz 、12、25Mhz 等)但是為什么這么設(shè)計呢?
主要的問題我不是特別清楚,說的可能不對,我個人理解如下:
1、內(nèi)部時鐘源使用RC 震蕩方式提供內(nèi)部基礎(chǔ)時鐘,內(nèi)部時鐘啟動速度較快但是存在對于溫度比較敏感,在芯片工作溫度上來之后會出現(xiàn)“溫飄“的現(xiàn)象,主要表現(xiàn)是整體系統(tǒng)時鐘頻率變化,有可能和外設(shè)外設(shè)工作不正常。
2、外部時鐘源主要是使用石英振蕩器或者其他設(shè)備的輸出時鐘源作為輸入時鐘源,具有頻率精準,對溫度不敏感(溫補晶振),適合作為精準的工作時鐘源,但是存在一個頻率穩(wěn)定的時鐘過程,另外也有可能存在外部晶振失效的異常情況。
因此bf 里面在系統(tǒng)啟動的時候先使用的是內(nèi)部時鐘源,然后在系統(tǒng)初始化過程中,切換到外部時鐘源,并使用PLL 控制整體系統(tǒng)的各部分時鐘。
4、bf 的時鐘初始化配置過程:
bf 在mcu上電之后,啟動過程如下
? Startup_at23F435_437.S??? reset_handler 初始化 中斷向量表、內(nèi)存段、PG參數(shù)
↓
Main.c? main()
↓
src/main/fc/init.c? init 函數(shù)
↓
src/main/drivers/System_at32f43x.c? SystemInit 函數(shù)
↓
src/main/drivers/startup/at32f435_437_clock.c? ????system_clock_config 函數(shù)
其中system_clock_config 函數(shù)就是用 at的 時鐘樹配置工具生成的代碼,具體如下
具體過程可以看詳細注釋,重點是最后一句: system_core_clock_update,重新配置systick 以及system_core_clock 全局變量為當前系統(tǒng)主頻數(shù)。
以上是我們對于at32 移植過程中時鐘樹的配置。