RCC : reset clock control 復位和時鍾控制器。
設置系統時鍾 SYSCLK、設置 AHB 分頻因子(決定 HCLK 等於多少) 、 設置 APB2 分頻因子(決定 PCLK2 等於多少)、設置 APB1 分頻因子(決定 PCLK1 等於多少)、設置各個外設的分頻因子;控制 AHB、 APB2 和 APB1 這三條總線時鍾的開啟、控制每個外設的時鍾的開啟。對於 SYSCLK、 HCLK、 PCLK2、 PCLK1 這四個時鍾的配置一般是: PCLK2 =HCLK = SYSCLK=PLLCLK = 72M, PCLK1=HCLK/2 = 36M。這個時鍾配置也是庫函數的標准配置,我們用的最多的就是這個.
時鍾樹圖
1 系統時鍾
1.①HSE 高速外部時鍾信號
HSE 是高速的外部時鍾信號,可以由有源晶振或者無源晶振提供,頻率從 4-16MHZ不等。當使用有源晶振時,時鍾從 OSC_IN 引腳進入, OSC_OUT 引腳懸空,當選用無源晶振時,時鍾從 OSC_IN 和 OSC_OUT 進入,並且要配諧振電容。
HSE 最常使用的就是 8M 的無源晶振。當確定 PLL 時鍾來源的時候, HSE 可以不分頻或者 2 分頻,這個由時鍾配置寄存器 CFGR 的位 17: PLLXTPRE 設置,我們設置為 HSE不分頻。
2. ②PLL 時鍾源
PLL 時鍾來源可以有兩個,一個來自 HSE,另外一個是 HSI/2,具體用哪個由時鍾配置寄存器 CFGR 的位 16: PLLSRC 設置。 HSI 是內部高速的時鍾信號,頻率為 8M,根據溫度和環境的情況頻率會有漂移,一般不作為 PLL 的時鍾來源。這里我選 HSE 作為PLL 的時鍾來源。
3. ③PLL 時鍾 PLLCLK
通過設置 PLL 的倍頻因子,可以對 PLL 的時鍾來源進行倍頻,倍頻因子可以是:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],具體設置成多少, 由時鍾配置寄存器 CFGR 的位21-18: PLLMUL[3:0]設置。我們這里設置為 9 倍頻,因為上一步我們設置 PLL 的時鍾來源為 HSE=8M,所以經過 PLL 倍頻之后的 PLL 時鍾: PLLCLK = 8M *9 = 72M。 72M 是 ST官方推薦的穩定運行時鍾,如果你想超頻的話,增大倍頻因子即可,最高為 128M。我們這里設置 PLL 時鍾: PLLCLK = 8M *9 = 72M。
4. ④系統時鍾 SYSCLK
系統時鍾來源可以是: HSI、 PLLCLK、 HSE,具體的時鍾配置寄存器 CFGR 的位 1-0:SW[1:0]設置。我們這里設置系統時鍾: SYSCLK = PLLCLK = 72M。
5. ⑤AHB 總線時鍾 HCLK
系統時鍾 SYSCLK 經過 AHB 預分頻器分頻之后得到時鍾叫 APB 總線時鍾,即 HCLK,分頻因子可以是:[1,2,4, 8, 16, 64, 128, 256, 512],具體的由時鍾配置寄存器 CFGR的位 7-4 : HPRE[3:0]設置。片上大部分外設的時鍾都是經過 HCLK 分頻得到,至於 AHB總線上的外設的時鍾設置為多少,得等到我們使用該外設的時候才設置,我們這里只需粗線條的設置好 APB 的時鍾即可。 我們這里設置為 1 分頻,即 HCLK=SYSCLK=72M。
6. ⑥APB2 總線時鍾 HCLK2
APB2 總線時鍾 PCLK2 由 HCLK 經過高速 APB2 預分頻器得到,分頻因子可以是:[1,2,4, 8, 16],具體由時鍾配置寄存器 CFGR 的位 13-11: PPRE2[2:0]決定。 HCLK2 屬於高速的總線時鍾,片上高速的外設就掛載到這條總線上,比如全部的 GPIO、 USART1、SPI1 等。至於 APB2 總線上的外設的時鍾設置為多少,得等到我們使用該外設的時候才設置,我們這里只需粗線條的設置好 APB2 的時鍾即可。我們這里設置為 1 分頻,即 PCLK2= HCLK = 72M。
7. ⑦APB1 總線時鍾 HCLK1
APB1 總線時鍾 PCLK1 由 HCLK 經過低速 APB 預分頻器得到,分頻因子可以是:[1,2,4,8, 16],具體的由時鍾配置寄存器 CFGR 的位 10-8: PRRE1[2:0]決定。HCLK1 屬於低速的總線時鍾,最高為 36M,片上低速的外設就掛載到這條總線上,比如USART2/3/4/5、 SPI2/3, I2C1/2 等。至於 APB1 總線上的外設的時鍾設置為多少,得等到我們使用該外設的時候才設置,我們這里只需粗線條的設置好 APB1 的時鍾即可。我們這里設置為 2 分頻,即 PCLK1 = HCLK/2 = 36M。
8. 設置系統時鍾庫函數
上面的 7 個步驟對應的設置系統時鍾庫函數如下,該函數截取自固件庫文件system_stm32f10x.c。 為了方便閱讀,我已把互聯型相關的代碼刪掉,把英文注釋翻譯成了中文,並把代碼標上了序號,總共七個步驟。該函數是直接操作寄存器的,有關寄存器部分請參考數據手冊的 RCC 的寄存器描述部分。
static void SetSysClockTo72(void) { // SYSCLK HCLK PCLK2 PCLK1 Configuration __IO uint32_t StartUpCounter = 0, HSEStatus = 0; // ① 使能 HSE,並等待 HSE 穩定 (外源頭晶振,需要等待時間) RCC->CR |= ((uint32_t)RCC_CR_HSEON); // 等待 HSE 啟動穩定,並做超時處理 do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while ((HSEStatus == 0) &&(StartUpCounter !=HSE_STARTUP_TIMEOUT)); if ((RCC->CR & RCC_CR_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } // HSE 啟動成功,則繼續往下處理 if (HSEStatus == (uint32_t)0x01) { //----------------------------------------------------------- // 使能 FLASH 預存取緩沖區 */ FLASH->ACR |= FLASH_ACR_PRFTBE; // SYSCLK 周期與閃存訪問時間的比例設置,這里統一設置成 2 // 設置成 2 的時候, SYSCLK 低於 48M 也可以工作,如果設置成 0 或者 1 的時候, // 如果配置的 SYSCLK 超出了范圍的話,則會進入硬件錯誤,程序就死了 // 0: 0 < SYSCLK <= 24M // 1: 24< SYSCLK <= 48M // 2: 48< SYSCLK <= 72M */ FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; //------------------------------------------------------------ // ② 設置 AHB、 APB2、 APB1 預分頻因子 // HCLK = SYSCLK RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; //PCLK2 = HCLK RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; //PCLK1 = HCLK/2 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; // ③ 設置 PLL 時鍾來源,設置 PLL 倍頻因子, PLLCLK = HSE * 9 = 72 MH RCC->CFGR &= (uint32_t)((uint32_t) ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); // ④ 使能 PLL RCC->CR |= RCC_CR_PLLON; // ⑤ 等待 PLL 穩定 while ((RCC->CR & RCC_CR_PLLRDY) == 0) { } // ⑥ 選擇 PLL 作為系統時鍾來源 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; // ⑦ 讀取時鍾切換狀態位,確保 PLLCLK 被選為系統時鍾 while ((RCC->CFGR&(uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){ } } else {// 如果 HSE 啟動失敗,用戶可以在這里添加錯誤代碼出來 } }
2 其他時鍾
1. A、 USB 時鍾
USB 時鍾是由 PLLCLK 經過 USB 預分頻器得到,分頻因子可以是: [1,1.5], 具體的由時鍾配置寄存器 CFGR 的位 22: USBPRE 配置。 USB 的時鍾最高是 48M,根據分頻因子反推過來算 , PLLCLK 只能是 48M 或者是 72M。一般我們設置 PLLCLK=72M,USBCLK=48M。 USB 對時鍾要求比較高,所以 PLLCLK 只能是由 HSE 倍頻得到,不能使用 HSI 倍頻。
2. B、 Cortex 系統時鍾
Cortex 系統時鍾由 HCLK 8 分頻得到,等於 9M, Cortex 系統時鍾用來驅動內核的系統定時器 SysTick, SysTick 一般用於操作系統的時鍾節拍,也可以用做普通的定時。
3. C、 ADC 時鍾
ADC 時鍾由 PCLK2 經過 ADC 預分頻器得到,分頻因子可以是[2,4,6,8],具體的由時鍾配置寄存器 CFGR 的位 15-14: ADCPRE[1:0]決定。 很奇怪的是怎么沒有 1 分頻。 ADC時鍾最高只能是 14M,如果采樣周期設置成最短的 1.5 個周期的話, ADC 的轉換時間可以達到最短的 1us。如果真要達到最短的轉換時間 1us 的話,那 ADC 的時鍾就得是 14M,反推 PCLK2 的時鍾只能是: 28M、 56M、 84M、 112M,鑒於 PCLK2 最高是 72M,所以只能取 28M 和 56M。
4. D、 RTC 時鍾、獨立看門狗時鍾
RTC 時鍾可由 HSE/128 分頻得到,也可由低速外部時鍾信號 LSE 提供,頻率為32.768KHZ,也可由低速內部時鍾信號 HSI 提供,具體選用哪個時鍾由備份域控制寄存器BDCR 的位 9-8: RTCSEL[1:0]配置。
獨立看門狗的時鍾由 LSI 提供,且只能是由 LSI 提供,LSI 是低速的內部時鍾信號,頻率為 30~60KHZ 直接不等,一般取 40KHZ。
5. E、 MCO 時鍾輸出
MCO 是 microcontroller clock output 的縮寫,是微控制器時鍾輸出引腳,在 STM32 F1系列中 由 PA8 復用所得,主要作用是可以對外提供時鍾,相當於一個有源晶振。 MCO 的時鍾來源可以是: PLLCLK/2、 HSI、 HSE、 SYSCLK,具體選哪個由時鍾配置寄存器CFGR 的位 26-24: MCO[2:0]決定。 除了對外提供時鍾這個作用之外, 我們還可以通過示波器監控 MCO 引腳的時鍾輸出來驗證我們的系統時鍾配置是否正確。