今天我們來學習一下時鍾,時鍾是單片機運行的基礎,任何的外設都需要使能相應的外設時鍾才能正常工作,在前面的兩章中我們都只是粗略的配置了一下時鍾樹。今天我們要具體分析一下時鍾系統框圖,掌握時鍾的相關概念以及學習一下定時器這一個外設。
基本概念
上圖中一個方波成為一個周期,之前我們也談過,對於方形脈沖,電平從低電平到高電平的那條豎線稱為上升沿,反之從高電平到低電平的稱為下降沿,時鍾信號就是這樣一個特殊的方波脈沖,
或者叫時鍾脈沖。
-
脈沖周期:兩個脈沖相繼出現的時間,脈沖周期是頻率的倒數
-
(脈沖)頻率:單位時間內(1秒)所產生的脈沖個數,頻率的單位有 GHz=1000MHz =1000kHz=1000Hz
-
時鍾源:產生時鍾脈沖的源頭,可以是外部晶振/陶瓷諧振器、RC振盪器等
-
倍頻:一種增大頻率的方法,使輸出頻率是輸入頻率的整數倍
-
分頻:一種減小頻率的方法,使輸出頻率是輸入頻率的整數倍分之一
時鍾——單片機的心臟
像人的生命活動需要心臟的跳動一樣,單片機的各部分執行指令也需要一個“心臟”,而這個”心臟“就是我們的時鍾。任何外設的使用都需要使能其外設時鍾。實際上即使我們不配置時鍾樹直接生成代碼,我們會發現在Startup_stm32f427xx.s啟動文件中,早已經有用匯編寫的代碼來初始化系統時鍾。
可以看出,在即使是STM32CubeMX生成的代碼中,RCC時鍾也是第一個使能的。其中RCC外設的全稱是Reset clock control,即復位和時鍾控制,這里主要是時鍾部分的控制,接下來我們再談談為什么沒有時鍾,單片機就無法正常工作。
在第一篇文章中我們說到,我們對單片機的控制,最底層的控制,就是對寄存器進行讀寫。這里在嵌入式中寄存器更偏重於兩種功能:讀和寫。當讀取一個寄存器時,可以把寄存器看作一個只能裝0或者1的抽屜,你打開抽屜看到的0或者1反應了單片機內部的一些工作狀態,或是有一組寄存器,單片機將一些數據通過二進制編碼把數據依次存入寄存器中,這時每個寄存器的0或者1就相當於數據某一位的0或者1。當對一個寄存器進行寫操作時,我們可以把一個寄存器置位(寫入1)或者復位(寫入0),這時寄存器更像一個開關,我們可以通過寫1或者0來開啟/關閉某個功能,CPU也可以進行同樣的讀寫操作。
那現在情況來了,外設產生了一個請求將寄存器A置位,假如CPU需要根據從寄存器A中讀取的0/1來決定是否對寄存器B寫1。CPU讀寄存器A是1也就是高電平,他將寄存器B置位。那CPU下次執行該操作時,他讀取到的寄存器A的高電平,他怎么判斷這是上一次的請求還是產生新的請求?
這時候就需要一個全局的時鍾信號來同步整個電路,時鍾信號給數字系統中每一個時序邏輯一個開始工作的時間點。再打個比方,時鍾信號就好比學生跑操時喊的“121212”的口令,所有的人(元器件)都是按照這個口令來邁左右腳的(工作),口令喊的越快,整個隊伍也就跑的越快,那是不是時鍾信號的頻率要越高越好呢?其實不然,當口令快到超過人抬放腳的頻率時,就好比有一個人跟不上口令就會絆倒其他人導致一些人都不能跟上隊伍一樣,電子元件也是有反應速度的,如果寫入數據的速度跟不上時鍾的變化速度,就會出現還未寫完數據時鍾信號就已經跳變無法寫入的情況。
所以,每一個外設在使能時都需要先使能其對應的外設時鍾,否則寄存器就無法正常讀寫,自然外設也就無法正常工作。而且我們時鍾頻率也有一定的要求,頻率既不能太快也不能太慢,只有合適的頻率單片機才能正常且高效地工作。
-
時鍾頻率過低:不能滿足設備的頻率需求,可能會無法啟動設備。
-
時鍾頻率在允許范圍內頻率越快,外設工作效率越高
-
時鍾頻率過高:功耗越大,造成浪費,同時電路的抗電磁干擾能力越弱,系統穩定性受影響
不同的外設對時鍾頻率的需求也不一樣,為了兼容不同速度的設備,有些高速,有些低速。MCU通常是采用多時鍾源的方法來解決這些問題,從而衍生出了時鍾系統和時鍾樹
時鍾樹與時鍾系統
上圖是STM32F4xx的時鍾系統框圖,在這里你可以看到所有的外設時鍾的來源,可能你會很疑惑,你沒有看到之前學過的像GPIO、EXTI等你熟悉的外設。先不用着急,等我分析完后你就能自己找到所有的外設時鍾,為了更好地與實操相結合,我們以STM32CubeMX中的時鍾樹配置框圖來講解時鍾樹系統。
我將STM32CubeMX中的時鍾樹圖縮小到可以截下全景,和上面的時鍾系統框圖對比后可以發現基本沒有差別,而我們重點要學習的就是紅框中的時鍾配置,因為核心功能和外設的配置都在里面,未框選的部分都是一些獨立的、使用頻率較低的外設,但是不代表這個外設不重要,比如RTC時鍾,像這些外設在你看完這篇文章后也會自己分析其時鍾的來源和配置。在學習時鍾樹時,我們要重點把握以下3點:
-
時鍾源
-
分/倍頻處理
-
輸出到什么外設
將時鍾圖放大后,我們來分析一下stm32的四個時鍾源
如圖所示,STM32主要有內部時鍾和外部時鍾,其中每種時鍾都有高速與低速之分,所以有4種時鍾源
HSE 高速外部時鍾信號
HSE: High Speed External Clock signal 即高速外部時鍾信號
在圖中可以看出HSE是由兩個引腳輸入時鍾信號(OSC_IN引腳和OSC_OUT引腳),輸入的信號頻率范圍是4~25MHz
HSE的輸入信號來源又分為兩種:
-
外部(旁路)時鍾源 BYPASS clock source
-
外部晶振/陶瓷諧振器 Crystal/Ceramic Resonator
當使用旁路時鍾源時,OSC_OUT腳懸空處於高阻態,時鍾源僅由OSC_IN腳輸入,時鍾信號占空比約為50%
當使用外部晶振/陶瓷諧振器時,電路中要搭配兩個諧振電容,時鍾信號由兩個腳(OSC_IN 和OSC_OUT)引入。
這些都能在STM32CubeMX中配置
HSE的頻率非常高,基本上是四個時鍾源中最高的一個,並且HSE的精度高,不容易受溫度影響,所以是使用最多的時鍾源。
在A型板的原理圖中我們可以看到晶振的頻率是12MHz,所以我們在CubeMX的Input frequency中填12
HSI 高速內部時鍾信號
HSI High Speed Internal Clock signal 即高速外部時鍾信號
HSI內部高速時鍾的時鍾來源是內部 16 MHz RC 振盪器, 雖說16MHz比HSE的外部高速時鍾頻率高,啟動速度也比HSE快,但是精度比不上HSE,HSI的時鍾信號受溫度影響特別大,有溫漂現象。所以HSI常作為備用時鍾,當HSE出現故障時,有中斷將HSI作為時鍾輸入讓系統恢復正常使用。但這只是權宜之計,並非萬全之策,最好的方法還是要采取相應的補救措施並報警,然后修復 HSE。臨時使用 HSI 只是為了把損失降低到最小,畢竟 HSI 較於 HSE 精度還是要低。
LSE 低速外部時鍾信號
Low Speed External Clock Signal 低速外部時鍾信號
與HSE一樣,LSE同樣有兩個時鍾源: 旁路時鍾源和外部晶振/陶瓷振盪器時鍾源。參考HSE即可。但是與HSE相比,LSE的晶振頻率就小了很多,LSE 晶振是 32.768 kHz 低速外部 (LSE) 晶振或陶瓷諧振器 。僅僅32.768kHz注意單位是kHz。從圖中可以看出,LSE的主要作用於RTC時鍾來提供時鍾和日歷等其他定時功能,具有功耗低和j精度高的特點。RTC時鍾也叫實時時鍾(Real Time Clock)和我們日常生活中的鍾表功能一樣,主要提供秒分時、星期、月份、年份等日歷功能,這里只做了解。
LSI 低速內部時鍾信號
Low Speed Internal Clock Signal 低速內部時鍾信號
LSI和HSI一樣是由RC振盪電路產生時鍾脈沖,時鍾頻率是32kHz,可作為低功耗時鍾源在停機和待機模式下保持運行,供獨立看門狗 (IWDG) 和自動喚醒單元 (AWU) 使用。
說到這里四種時鍾源就已經全部介紹完畢了,概括地說內部時鍾是在芯片內部RC振盪器產生的,起振較快,所以時鍾在芯片剛上電的時候,默認使用內部高速時鍾。而外部時鍾信號是由外部的晶振輸入的,在精度和穩定性上都有很大優勢,所以上電之后我們再通過軟件配置,轉而采用外部時鍾信號。
PLL時鍾
PLL(Phase Locked Loop),中文叫做鎖相環或是鎖相回路,經過鎖相環輸出的信號稱為鎖相環時鍾信號
PLL 的主要作用是對時鍾進行倍頻 再進行輸出。STM32F4xx的系統時鍾(SYSCLK)官方推薦的最高穩定時鍾可以達到180MHz頻率(當然可以超頻,但是不推薦),這18Mhz由晶振是很難實現的,所以需要經過一個倍頻器來放大,PLL就是這樣一個倍頻電路。PLL有兩個:一個是主PLL( Main PLL),另一個是I2S專用的PLLI2S。現在我們來分析一下主PLL時鍾。
首先是PLL時鍾的輸入,1處的梯形是PLL時鍾源選擇器(PLL Source Mux),他可以選擇輸入PLL電路的時鍾源是哪個。這里PLL時鍾的輸入時鍾源只有HSE和HSI,輸入之后信號經過M分頻因子(2處)分頻,輸入到PLL內部的一個叫VCO的亞控振盪器內。
這個VCO可以產生高頻信號,VCO對輸入和輸出信號頻率都有要求:輸入VCO的信號頻率必須在1~2MHz之間,所以有M分頻因子將HSE或者HSI信號分頻后輸入;VCO輸出的高頻信號又必須在193到432之間,所以會有N倍頻因子(3處)將信號倍頻作為VCO的輸出。STM32F427中,VCO的輸出有兩個分頻因子(不要忘了系統時鍾最高是180MHz):分頻因子P可以對信號進行2、4、6、8分頻之后可以作為系統時鍾的輸入;分配因子Q取值從4 ~15 不等,分頻后作為 USB OTG FS的時鍾。
這里有個很有意思的事情, USB OTG FS的時鍾頻率必須是使用48MHz,但是如果我們想要系統時鍾達到官方推薦的180MHz,那么VCO的輸出在 經過分頻因子P之前的時鍾頻率是360Mhz,而360MHz/48MHz=7.5,也就是說如果要360MHz分頻成48MHz得7.5分頻,而分頻因子必須是整數。所以48MHz的USB OTG FS時鍾和180MHz的系統時鍾不可兼得,要想使用USB功能,常常退而求其次,將系統時鍾配置成168MHz。這也就是為什么HCLK的下面寫着180MHz MAX而我們經常配置成168MHz的原因。
網上有許多說法說STM32有5個時鍾源:HSE、HSI、LSE、LSI、PLL。但是通過上面的分析我們可以看出,PLL時鍾其實不算一個獨立的時鍾源,PLL時鍾源的輸入是HSE或者HSI,PLL本身只是起到一個倍頻的作用,不能獨立輸出時鍾信號。
SYSCLK 系統時鍾
System Clock 系統時鍾
系統時鍾的時鍾源輸入由System Clock Mux選擇,有HSE、HSI、PLL三個輸入,但是要想達到25MHz以上的頻率,只能由PLL作為時鍾源輸入,此外還可以配置CSS,即時鍾監視系統。當使能CSS 使能后,如果 HSE 時鍾偶發故障失效時, CSS 將生成一個中斷,進而促使 NMI 自動生成 。NMI即上一篇文章中說到的Non Maskable Interrupt,不可屏蔽中斷。該中斷的優先級相當高,是負數,而且CPU不可屏蔽。在進入NMI中斷后,系統時鍾會禁止HSE並使能HSI作為緊急搶救,保護系統正常工作。
系統時鍾是供STM32中絕大部分部件工作的時鍾源。除了直接作為以太網PTP時鍾源外,系統時鍾都經過了AHB預分頻器(AHB Prescaler)后輸送給5大模塊。但是我們通常都是AHBPrescaler設置成1分頻也就是不分頻,像HCLK和FCLK時鍾的頻率都是系統時鍾的頻率。這一塊STM32CubeMX的時鍾樹和STM32F4XX中文參考手冊時鍾樹有出入,為了准確性我還是選擇用STM32F4xx中文參考手冊。
系統時鍾(SYSCLK)信號經過AHB預分頻器后主要有5個去向。
-
HCLK:中文叫AHB總線時鍾、頻率和SYSCLK一樣,將時鍾信號提供給存儲器,DMA及cortex內核,我們說的MCU主頻一般指HCLK的頻率,他頻率的高低決定了執行代碼速度的快慢
-
八分頻后輸送到系統定時器(Systick)
-
FCLK: Free run clock 自由運行時鍾,自由表示FCLK並不來源於HCLK,所以HCLK停止時FCLK也正常運行,FCLK和HCLK信號互相同步,在休眠模式下通過FCLK依舊可以采樣到中斷和跟蹤休眠事件
-
經過APB1分頻器分頻后直接供給APB1總線外設,或是再倍頻給掛載在APB1總線上的定時器,APB1總線時鍾(PCLK1)頻率最高是45MHz
-
經過APB2分頻器分頻后直接供給APB2總線外設,或是再倍頻給掛載在APB2總線上的定時器,APB2總線時鍾(PCLK2)頻率最高是90MHz
再來說說總線(BUS)的概念:外設與外設、外設與內核之間要進行數據、指令交換,但是外設的數量非常龐大,如果全部一一對應建立數據通道的話非常麻煩,所以有了總線這一種特殊布線方式,總線可以理解成一輛數據公交車(也就是BUS),公交車會歷遍全部站點,所有的外設或者內核都能將數據送上”BUS“,“到站的數據”也能下車到對應的外設。
那這里出現了2條總線:
-
AHB總線:(Advanced High performance Bus),高性能總線,是一種系統總線,它主要負責連接處理器、DMA等一些內部接口。
-
APB總線:(Advanced Peripheral Bus),片上外設總線,它主要負責連接外圍設備,它又分為APB1和APB2。
上圖是STM32F427和F429的總線架構圖,可以看到芯片內部的一些片上外設如DMA、GPIO等是掛載在AHB總線上,APB2上掛載的是一些高速外設如TIM1,TIM8,USART1、ADC等,時鍾頻率比較低的外設就掛載在APB1上,如TIM2~5 、UART4等等。這些都可以在芯片資料表里面查閱到。
至此,系統時鍾的時鍾信號走向都介紹完了,可以看到,系統時鍾(SYSCLK)是非常重要的,這也是為什么HSE作為系統時鍾的輸入時鍾源時會有CSS時鍾監視系統來保證SYSCLK一直有時鍾信號輸入,SYSCLK下游的HCLK(AHB總線時鍾)、FCLK(自由運行時鍾)SysTick(系統定時器)、PCLK1(APB1總線時鍾)、PCLK2(APB2總線時鍾)幾乎涵蓋了我們日常使用的全部外設,所以掌握這些時鍾的配置,對我們能夠正常使用外設具有很重要的意義。
至於為什么要有那么多的時鍾源,意義有兩個:
-
兼容不同工作頻率的外設,避免功耗過大造成資源浪費
-
多個時鍾源可以防止出現單一時鍾故障而整體工作癱瘓的問題
總結
通過本篇文章的學習,我們需要重點掌握以下內容
-
時鍾頻率的概念
-
為什么使用外設需要先使能外設時鍾?
-
時鍾樹時鍾信號3要點: 時鍾源是什么?、哪些分/倍頻處理?、時鍾信號輸出流向哪?
-