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