1. 程式人生 > >Cortex-M3 入門指南(三):時鐘總線與復位時鐘控制器

Cortex-M3 入門指南(三):時鐘總線與復位時鐘控制器

關系 有著 寄存器 系統時鐘 實時時鐘 參數 www 開發 正整數

【reset clock control 復位和時鐘控制器】

時鐘信號對於處理器非常重要,比如我們熟悉的 CPU 就是由時鐘信號驅動的,而主頻就是內核的的時鐘信號頻率。Cortex-M3 有著復雜的時鐘樹架構,而且我們需要在初始化階段配置好時鐘參數。

本文將會先介紹時鐘相關的概念,然後介紹使用庫函數便捷設置時鐘總線的方法,在文章最後再深入學習庫函數背後等效的時鐘寄存器原理。

時鐘源

STM32F103 中有 4 種可選時鐘源:

  1. 高速外部時鐘 (HSE): 以外部晶振作時鐘源,晶振頻率可取範圍為 4~16 MHz,常用 8MHz 晶振,開發板上的 8MHz 時鐘就是指的這個。
  2. 高速內部時鐘 (HSI): 由內部 RC 振蕩器產生,頻率為8MHz, 無須外接晶振,但精確性比外部時鐘差。
  3. 低速外部時鐘 (LSE): 以外部晶振作時鐘源,可以提供時鐘信號給實時時鐘模塊,一般采用 32.768KHz 晶振,較為少用。
  4. 低速內部時鐘 (LSI): 由內部 RC 振蕩器產生,也主要提供信號給實時時鐘模塊,頻率在 30-60KHz 間浮動,較為少用。

單片機啟動時默認使用高速內部時鐘 (HSI),啟動之後可以通過 RCC 時鐘控制寄存器器改用其他時鐘源。

系統時鐘 (SYSCLK)

系統時鐘 SYSCLK 最大頻率為 72MHz,它是供 STM32 中絕大部分部件工作的時鐘源。系統時鐘可由 PLL(鎖相環)、HSI 或者 HSE 提供輸入,並且通過 AHB(高速總線) 分頻器分頻後輸出送給各模塊使用。

鎖相環 (PLL)

如果打算使單片機運行在最高頻率 (72 MHz),我們還需要倍頻高速時鐘源的時鐘信號。鎖相環能夠將輸出頻率鎖定在輸入頻率的正整數倍。STM32F103 的鎖相環提供了 2 到 16 倍的倍頻系數。假設我們使用高速內部時鐘源 (8 MHz) ,想要使 STM32F103 達到最高主頻 (72 MHz),那麽我們就要要啟用鎖相環,設置為 9 倍倍頻,並將 SYSCLK 時鐘源設置為 PLL。

時鐘總線

STM32F103 中有 4 條時鐘總線:

  • AHB 高速總線,時鐘為 HCLK,最大頻率為 72 MHz,時鐘信號提供給存儲器,DMA 及 Cortex 內核,是內核運行的時鐘,也就是主頻,它的大小與 STM32 運算速度,數據存取速度密切相關。
  • APB1 低速外設總線,時鐘為 PCLK1,最大頻率為 36 MHz,提供給掛載在APB1總線上的外設, 如 USART2
  • APB2 高速外設總線,時鐘為 PCLK2,最大頻率為 72 MHz,提供給掛載在APB2總線上的外設,如 GPIO, USART1
  • FCLK 自由運行時鐘,獨立於內核運行,一般設置為與 HCLK 同頻率,常用於采樣中斷和調試模塊供時。

使用庫函數設置 復位時鐘控制器 (RCC)

復位時鐘控制器是 STM32F103 提供的一組寄存器,負責控制和設置上面提到的時鐘源,鎖相環倍頻,各總線分頻系數以及開關總線上的各類外設。

stm32f1xx_hal 提供了簡潔的接口幫我們設置 RCC 寄存器,足夠滿足日常工作需要。工程上也推薦使用這種方式進行時鐘樹初始化。

下面例子中單片機使用外部 8MHz 晶振,並將所有總線設置為最高頻率:

#![no_main]
#![no_std]

extern crate cortex_m;
extern crate cortex_m_rt as rt;
extern crate panic_halt;
extern crate stm32f103xx_hal as hal;

use hal::prelude::*;
use hal::stm32f103xx;
use rt::entry;

#[entry]
fn main() -> ! {
    let dp = stm32f103xx::Peripherals::take().unwrap();

    let mut flash = dp.FLASH.constrain();
    let mut rcc = dp.RCC.constrain();

    let clocks = rcc
        .cfgr
        .use_hse(8.mhz())   // 高速外部時鐘源
        .sysclk(72.mhz())   // 系統時鐘
        .hclk(72.mhz())     // AHB 高速總線
        .pclk1(36.mhz())    // APB1 低速外設總線
        .pclk2(72.mhz())    // APB2 高速外設總線
        .freeze(&mut flash.acr);    // 應用時鐘配置

    loop {}
}

深入了解 RCC 寄存器

RCC 寄存器的設置比其他一般外設寄存器要更為復雜,因此一般不會手動設置。但是我們可以通過學習它來掌握的庫函數背後的原理。

RCC 時鐘設置一般分為以下幾個步驟:

  1. 啟用外部晶振 (可選)
  2. 等待外部晶振穩定
  3. 設置各總線分頻系數
  4. 設置 FLASH 等待系數與預讀取
  5. 啟動鎖相環
  6. 等待鎖相環鎖定
  7. 將 SYSCLK 切換到鎖相環信號輸入

PS: 這裏提到的 FLASH 等待系數和預讀取都與 Cortex-M 架構設計有關。Cortex-M 核心采用了三級管道技術,簡單來說就是當一個指令正在處理時,下一個指令已經被解碼的同時第三個指令已經被預讀取進緩存區了,這鐘處理方式能夠大幅提高處理器的運行效率。另外,FLASH 由於原理限制,很難達到與核心相同的高頻率,因此在核心讀取指令的速度超過 FLASH 發送指令速度的時候,核心需要暫時停下來等待。根據手冊,STM32F103 的 FLASH 等待系數應根據核心頻率 (HCLK) 設置:

HCLK        | FLASH WAIT STATE
-------------------------------
0 - 24 MHz  | 0 wait state
24 - 48 MHz | 1 wait state
48 - 72 MHz | 2 wait state

分頻

事實上,AHB,APB1,APB2 等各總線的頻率都嚴格成正整數倍關系,因為它們的時鐘信號並不是單獨產生的,而是根據特定結構分頻出來的。分頻就是按照預分頻系數降低輸入頻率,預分頻系數都為正整數。STM32F103 中的時鐘樹簡化之後是這樣的:

技術分享圖片

Example

我們這裏用寄存器代替庫函數初始化時鐘樹,代碼與上節的庫函數完全等效。下面用到的寄存器有 RCC_CRRCC_CFGRFLASH_ACR,由於篇幅較長,手冊截圖將放在後面以供參考。

use stm32f103xx;

pub fn rcc_clock_init(rcc: &mut stm32f103xx::RCC, flash: &mut stm32f103xx::FLASH) {
    // 啟動外部高速時鐘 (HSE)
    rcc.cr.write(|w| w.hseon().enabled());

    // 等待外部高速時鐘穩定
    while !rcc.cr.read().hserdy().is_ready() {}

    // 設置分頻 AHB(HCLK) = SYSCLK, APB1(PCLK1) = SYSCLK / 2, APB2(PCK2) = SYSCLK
    rcc.cfgr
        .write(|w| w.hpre().no_div().ppre1().div2().ppre2().no_div());

    // 設置鎖相環為 9 x HSE
    rcc.cfgr
        .write(|w| w.pllsrc().external().pllxtpre().no_div().pllmul().mul9());

    // 設置 flash : two wait states, 啟用預讀取
    flash.acr.write(|w| w.latency().two().prftbe().enabled());

    // 啟動鎖相環
    rcc.cr.write(|w| w.pllon().enabled());

    // 等待鎖相環鎖定
    while !rcc.cr.read().pllrdy().is_locked() {}

    // 使用鎖相環輸出作為 SYSCLK
    rcc.cfgr.write(|w| w.sw().pll());

    // 等待 SYSCLK 切換為鎖相環
    while !rcc.cfgr.read().sws().is_pll() {}
}

RCC 寄存器手冊 (P85)

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

Reference

[CSDN] STM32F10X的時鐘樹及時鐘初始化

STM32中的幾個時鐘SysTick、FCLK、SYSCLK、HCLK

[CSDN] RCC 復位與時鐘控制

原文鏈接:Cortex-M3 入門指南(三):時鐘總線與復位時鐘控制器 - 知乎 https://zhuanlan.zhihu.com/p/57918979

Cortex-M3 入門指南(三):時鐘總線與復位時鐘控制器