1.概述
時鐘是單片機的脈搏,是單片機的驅動源,使用任何一個外設都必須打開相應的時鐘。這樣的好處是,如果不使用一個外設的時候,就把它的時鐘關掉,從而可以降低系統的功耗,達到節能,實現低功耗的效果。
每個時鐘tick,系統都會處理一步數據,這樣才能讓工作不出現紊亂。
2.原理
首先,任何外設都需要時鐘,51單片機,STM32,430等等,因為寄存器是由D觸發器組成的,往觸發器里面寫東西,前提條件是有時鐘輸入。
51單片機不需要配置時鐘,是因為一個時鐘開了之后所有的功能都可以用了,而這個時鐘是默認開啟的,比如有一個水庫,水庫有很多個門,這些門默認是開啟的,所以每個門都會出水,我們需要哪個門的水的時候可以直接用,但是也存在一個問題,其他沒用到的門也在出水,即也在耗能。這里水庫可以認為是能源,門可以認為是每個外設的使用狀態,時鐘可以認為是門的開關。
STM32之所以是低功耗,他將所有的門都默認設置為disable,在你需要用哪個門的時候,開哪個門就可以,也就是說用到什么外設,只要打開對應外設的時鐘就可以,其他的沒用到的可以還是disable,這樣耗能就會減少。
在51單片機中一個時鐘把所有的都包了,而stm32的時鐘是有分工的,并且每類時鐘的頻率不一樣,因為沒必要所有的時鐘都是最高頻率,只要夠用就行,好比一個門出來水流大小,我只要洗臉,但是出來的是和洪水一樣涌出來的水,那就gg了,消耗能源也多,所以不同的時鐘也會有頻率差別,或者在配置的時候可以配置時鐘分頻。
拓展:為何要先配置時鐘,再配置GPIO(功能模塊)
所有寄存器都需要時鐘才能配置,寄存器是由D觸發器組成的,只有送來了時鐘,觸發器才能被改寫值。
任何MCU的任何外設都需要有時鐘,8051也是如此;STM32為了讓用戶更好地掌握功耗,對每個外設的時鐘都設置了開關,讓用戶可以精確地控制,關閉不需要的設備,達到節省供電的目的。
51單片機不用配置IO時鐘,只是因為默認使用同一個時鐘,這樣是方便,但是這樣的話功耗就降低不了。例如,某個功能不需要,但是它還是一直運行。
stm32需要配置時鐘,就可以把不需要那些功能的功耗去掉。當你想關閉某個IO的時候,關閉它相對應的時鐘使能就是了,不過在51里面,在使用IO的時候是沒有設置IO的時鐘的。
在STM32中,有外部和內部時鐘之分。ARM的芯片都是這樣,外設通常都是給了時鐘后,才能設置它的寄存器(即才能使用這個外設)。STM32、LPC1XXX等等都是這樣。這么做的目的是為了省電,使用了所謂時鐘門控的技術。這也屬于電路里同步電路的范疇:同步電路總是需要1個時鐘。
3.詳述STM32時鐘
STM32時鐘系統主要的目的就是給相對獨立的外設模塊提供時鐘,也是為了降低整個芯片的耗能。
系統時鐘,是處理器運行時間基準(每一條機器指令一個時鐘周期)
乍一看很嚇人,但其實很好理解,我們看系統時鐘SYSCLK 的左邊 系統時鐘有很多種選擇,而左邊的部分就是設置系統時鐘使用那個時鐘源。
系統時鐘SYSCLK 的右邊,則是系統時鐘通過AHB預分頻器,給相對應的外設設置相對應的時鐘頻率。
從左到右可以簡單理解為:
各個時鐘源—>系統時鐘來源的設置—>各個外設時鐘的設置
時鐘源
在STM32中,可以用內部時鐘,也可以用外部時鐘,在要求進度高的應用場合最好用外部晶體震蕩器,內部時鐘存在一定的精度誤差。
準確的來說有4個時鐘源可以選分別是HSI、LSI、HSE、LSE(即內部高速,內部低速,外部高速,外部低速),高速時鐘主要用于系統內核和總線上的外設時鐘。低速時鐘主要用于獨立看門狗IWDG、實時時鐘RTC。
HSI是高速內部時鐘,RC振蕩器,頻率為8MHz,上電后默認的系統時鐘 SYSCLK = 8MHz,Flash編程時鐘。
HSE是高速外部時鐘,可接石英/陶瓷諧振器,或者接外部時鐘源,頻率范圍為4MHz~16MHz。
LSI是低速內部時鐘,RC振蕩器,頻率為40kHz,可用于獨立看門狗IWDG、實時時鐘RTC。
LSE是低速外部時鐘,接頻率為32.768kHz的石英晶體。
PLL為鎖相環倍頻輸出,其時鐘輸入源可選擇為HSI/2、HSE或者HSE/2。倍頻可選擇為2~16倍,但是其輸出頻率最大不得超過72MHz。通過倍頻之后作為系統時鐘的時鐘源
( 網上有很多人說是5個時鐘源,這種說法有點問題,學習之后就會發現PLL并不是自己產生的時鐘源,而是通過其他三個時鐘源倍頻得到的時鐘)
舉個例子:Keil編寫程序是默認的時鐘為72Mhz,其實是這么來的:外部晶振(HSE)提供的8MHz(與電路板上的晶振的相關)通過PLLXTPRE分頻器后,進入PLLSRC選擇開關,進而通過PLLMUL鎖相環進行倍頻(x9)后,為系統提供72Mhz的系統時鐘(SYSCLK)。之后是AHB預分頻器對時鐘信號進行分頻,然后為低速外設提供時鐘。
或者內部RC振蕩器(HSI) 為 8MHz /2 為4MHz,進入PLLSRC選擇開關,通過PLLMUL鎖相環進行倍頻(x18)后為72MHz。
系統時鐘
系統時鐘SYSCLK可來源于三個時鐘源:
①、HSI振蕩器時鐘
②、HSE振蕩器時鐘
③、PLL時鐘
最大為72Mhz
PLL 鎖相環倍頻(輸入和輸出)
PLL的輸入3種選擇:
①、PLLi = HSI /2
①、PLLi = HSE /2
③、PLLi = HSE
PLL的輸出有15種選擇:PLLout = PLLi Xn (n = 2…16)
USB時鐘
STM32中有一個全速功能的USB模塊,其串行接口引擎需要一個頻率為48MHz的時鐘源。該時鐘源只能從PLL輸出端獲取(唯一的),可以選擇為1.5分頻或者1分頻,也就是,當需要使用USB模塊時,PLL必須使能,并且時鐘頻率配置為48MHz或72MHz。
把時鐘信號輸出到外部
STM32可以選擇一個時鐘信號輸出到MCO腳(PA8)上,可以選擇為PLL輸出的2分頻、HSI、HSE、或者系統時鐘。可以把時鐘信號輸出供外部使用。
系統時鐘通過AHB分頻器給外設提供時鐘(右邊的部分)?重點!!!
從左到右可以簡單理解為:
系統時鐘—>AHB分頻器—>各個外設分頻倍頻器 —> 外設時鐘的設置
右邊部分為:系統時鐘SYSCLK通過AHB分頻器分頻后送給各模塊使用,AHB分頻器可選擇1、2、4、8、16、64、128、256、512分頻。
其中AHB分頻器輸出的時鐘送給5大模塊使用:
①內核總線:送給AHB總線、內核、內存和DMA使用的HCLK時鐘。
②Tick定時器:通過8分頻后送給Cortex的系統定時器時鐘。
③I2S總線:直接送給Cortex的空閑運行時鐘FCLK。
④APB1外設:送給APB1分頻器。APB1分頻器可選擇1、2、4、8、16分頻,其輸出一路供APB1外設使用(PCLK1,最大頻率36MHz),另一路送給通用定時器使用。該倍頻器可選擇1或者2倍頻,時鐘輸出供定時器2-7使用。
⑤APB2外設:送給APB2分頻器。APB2分頻器可選擇1、2、4、8、16分頻,其輸出一路供APB2外設使用(PCLK2,最大頻率72MHz),另一路送給高級定時器。該倍頻器可選擇1或者2倍頻,時鐘輸出供定時器1和定時器8使用。
另外,APB2分頻器還有一路輸出供ADC分頻器使用,分頻后送給ADC模塊使用。ADC分頻器可選擇為2、4、6、8分頻。
需要注意的是,如果 APB 預分頻器分頻系數是 1,則定時器時鐘頻率 (TIMxCLK) 為 PCLKx。否則,定 時器時鐘頻率將為 APB 域的頻率的兩倍:TIMxCLK = 2xPCLKx。
APB1 和 APB2對應外設
F4系列:
APB2總線:高級定時器timer1, timer8、通用定時器timer9, timer10, timer11、UTART1,USART6
APB1總線:通用定時器timer2、timer5、通用定時器timer12、timer14、基本定時器timer、timer7、UTART2~UTART5。
F4系列的系統時鐘頻率最高能到168M
具體可以在 stm32f40x_rcc.h 中查看
或者通過 STM32參考手冊搜索“系統架構”或者“系統結構”查看外設掛在哪個時鐘下
RCC相關寄存器
Reset and clock control (RCC):時鐘配置,控制提供給各模塊時鐘信號的通斷。
以F1系列為例:
RCC 寄存器結構,RCC_TypeDeff,在文件“stm32f10x.h”中定義如下
?
typedef?struct { vu32 CR; //HSI,HSE,CSS,PLL等的使能 vu32?CFGR;?????????//PLL等的時鐘源選擇以及分頻系數設定 vu32?CIR;??????????//?清除/使能?時鐘就緒中斷 vu32?APB2RSTR;?????//APB2線上外設復位寄存器 vu32?APB1RSTR;?????//APB1線上外設復位寄存器 vu32?AHBENR;???????//DMA,SDIO等時鐘使能 vu32?APB2ENR;??????//APB2線上外設時鐘使能 vu32?APB1ENR;????? //APB1線上外設時鐘使能 vu32?BDCR;?????????//備份域控制寄存器 vu32 CSR; } RCC_TypeDef;
?
RCC初始化
這里我們使用HSE(外部時鐘),正常使用的時候也都是使用外部時鐘
使用HSE時鐘,程序設置時鐘參數流程:
1、將RCC寄存器重新設置為默認值 RCC_DeInit;
2、打開外部高速時鐘晶振HSE RCC_HSEConfig(RCC_HSE_ON);
3、等待外部高速時鐘晶振工作 HSEStartUpStatus = RCC_WaitForHSEStartUp();
4、設置AHB時鐘 RCC_HCLKConfig;
5、設置高速AHB時鐘 RCC_PCLK2Config;
6、設置低速速AHB時鐘 RCC_PCLK1Config;
7、設置PLL RCC_PLLConfig;
8、打開PLL RCC_PLLCmd(ENABLE);
9、等待PLL工作 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
10、設置系統時鐘 RCC_SYSCLKConfig;
11、判斷是否PLL是系統時鐘 while(RCC_GetSYSCLKSource() != 0x08)
12、打開要使用的外設時鐘
RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd()
代碼實現
?
對RCC的配置函數(使用外部8MHz晶振) 系統時鐘72MHz,APH 72MHz,APB2 72MHz,APB1 32MHz,USB 48MHz TIMCLK=72M void RCC_Configuration(void) { //----------使用外部RC晶振----------- RCC_DeInit(); //初始化為缺省值 RCC_HSEConfig(RCC_HSE_ON); //使能外部的高速時鐘 while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); //等待外部高速時鐘使能就緒 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer FLASH_SetLatency(FLASH_Latency_2); //Flash 2 wait state RCC_HCLKConfig(RCC_SYSCLK_Div1); //HCLK = SYSCLK RCC_PCLK2Config(RCC_HCLK_Div1); //PCLK2 = HCLK RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK1 = HCLK/2 RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); //PLLCLK = 8MHZ * 9 =72MHZ RCC_PLLCmd(ENABLE); //Enable PLLCLK while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait till PLLCLK is ready RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock while(RCC_GetSYSCLKSource()!=0x08); //Wait till PLL is used as system clock source //---------打開相應外設時鐘-------------------- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能APB2外設的GPIOA的時鐘 }
?
時鐘監視系統
STM32還提供了一個時鐘監視系統(CSS),用于監視高速外部時鐘(HSE)的工作狀態。
倘若HSE失效,會自動切換(高速內部時鐘)HSI作為系統時鐘的輸入,保證系統的正常運行。
?
審核編輯:湯梓紅
評論
查看更多