日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32学习之总线与时钟

發布時間:2025/3/15 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32学习之总线与时钟 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

上一篇博客復習了C語言,這一篇博客主要是學習STM32F407中的總線與時鐘,這一部分對計算機組成原理的知識有一定的要求,

這一部分極其枯燥,但是十分重要,望仔細學習

學習資料來自:STM32F407最小系統板開發指南-庫函數版本_V1.1.pdf
正點原子,感謝原子哥的開源奉獻
正點原子資料下載中心

STM32單片機學習資料均來自 正點原子 ,僅用于學習,如有侵權請聯系我刪除
本博客內容原創,創作不易,轉載請注明

本文鏈接
個人博客:https://ronglin.fun/?p=115
PDF鏈接:見博客網站
CSDN: https://blog.csdn.net/RongLin02/article/details/121308080

總線

總線

STM32F4 的總線架構比 51 單片機就要強大很多了。
STM32F4 總線架構的知識可以在《STM32F4XX 中文參考手冊》第二章有講解,這里我們也把這一部分知識抽取出來講解,是為了大家在學習 STM32F4 之前對系統架構有一個初步的了解。
這里的內容基本也是從中文參考手冊中參考過來的,讓大家能通過我們手冊也了解到,免除了到處找資料的麻煩吧。
如果需要詳細深入的了解 STM32 的系統架構,還需要多看看《STM32F4XX 中文參考手冊》或者在網上搜索其他相關資料學習。
我們這里所講的 STM32F4 系統架構主要針對的 STM32F407 系列芯片。

架構圖

首先我們看看STM32 的總線架構圖:

主系統由 32 位多層 AHB 總線矩陣構成。
總線矩陣用于主控總線之間的訪問仲裁管理。仲裁采取循環調度算法。總線矩陣可實現以下部分互聯:
八條主控總線是:

  • Cortex-M4 內核 I 總線, D 總線和 S 總線;
  • DMA1 存儲器總線, DMA2 存儲器總線;
  • DMA2 外設總線;
  • 以太網 DMA 總線;
  • USB OTG HS DMA 總線;
    七條被控總線
  • 內部 FLASH ICode 總線;
  • 內部 FLASH DCode 總線;
  • 主要內部 SRAM1(112KB)
  • 輔助內部 SRAM2(16KB);
  • 輔助內部 SRAM3(64KB) (僅適用 STM32F42xx 和 STM32F43xx 系列器件);
  • AHB1 外設 和 AHB2 外設;
  • FSMC;

功能講解

下面我們具體講解一下圖中幾個總線的知識。

  • I 總線(S0):
    此總線用于將 Cortex-M4 內核的指令總線連接到總線矩陣。內核通過此總線獲取指令。此總線訪問的對象是包括代碼的存儲器。
  • D 總線(S1):
    此總線用于將 Cortex-M4 數據總線和 64KB CCM 數據 RAM 連接到總線矩陣。內核通過此總線進行立即數加載和調試訪問。
  • S 總線(S2):
    此總線用于將 Cortex-M4 內核的系統總線連接到總線矩陣。此總線用于訪問位于外設或 SRAM 中的數據。
  • DMA 存儲器總線(S3,S4):
    此總線用于將 DMA 存儲器總線主接口連接到總線矩陣。DMA 通過此總線來執行存儲器數據的傳入和傳出。
  • DMA 外設總線:
    此總線用于將 DMA 外設主總線接口連接到總線矩陣。DMA 通過此總線訪問 AHB 外設或執行存儲器之間的數據傳輸。
  • 以太網 DMA 總線:
    此總線用于將以太網 DMA 主接口連接到總線矩陣。以太網 DMA通過此總線向存儲器存取數據。
  • USB OTG HS DMA 總線(S7):
    此總線用于將 USB OTG HS DMA 主接口連接到總線矩陣。USB OTG HS DMA 通過此總線向存儲器加載/存儲數據。
  • 對于系統架構的知識,在剛開始學習 STM32 的時候只需要一個大概的了解,大致知道是個什么情況即可。對于尋址之類的知識,這里就不做深入的講解,中文參考手冊都有很詳細的講解。

    時鐘

    STM32F4 時鐘系統的知識在《STM32F4 中文參考手冊》第六章復位和時鐘控制章節有非常詳細的講解,網上關于時鐘系統的講解也基本都是參考的這里,講不出啥特色,這些知識也不是什么原創,純粹根據官方提供的中文參考手冊和自己的應用心得來總結的,如有不合理之處望大家諒解。
    這部分對于計算機組成原理的知識有一定的要求

    STM32F4 時鐘樹概述

    眾所周知,時鐘系統是 CPU 的脈搏,就像人的心跳一樣。所以時鐘系統的重要性就不言而喻了。
    STM32F4 的時鐘系統比較復雜,不像簡單的 51 單片機一個系統時鐘就可以解決一切。
    于是有人要問,采用一個系統時鐘不是很簡單嗎?為什么 STM32 要有多個時鐘源呢?
    因為首先 STM32 本身非常復雜,外設非常的多,但是并不是所有外設都需要系統時鐘這么高的頻率,比如看門狗以及 RTC 只需要幾十 k 的時鐘即可。同一個電路,時鐘越快功耗越大,同時抗電磁干擾能力也會越弱,所以對于較為復雜的 MCU 一般都是采取多時鐘源的方法來解決這些問題。

    總述

    首先讓我們來看看 STM32F4 的時鐘系統圖

    在 STM32F4 中,有 5 個最重要的時鐘源,為 HSI、HSE、LSI、LSE、PLL。
    其中 PLL 實際是分為兩個時鐘源,分別為主 PLL 和專用 PLL。
    從時鐘頻率來分可以分為高速時鐘源和低速時鐘源,在這 5 個中 HSI,HSE 以及 PLL 是高速時鐘,LSI 和 LSE 是低速時鐘。
    從來源可分為外部時鐘源和內部時鐘源,外部時鐘源就是從外部通過接晶振的方式獲取時鐘源,其中 HSE 和LSE 是外部時鐘源,其他的是內部時鐘源。

    功能講解

  • LSI 是低速內部時鐘,RC 振蕩器,頻率為 32kHz 左右。供獨立看門狗和自動喚醒單元使用。
  • LSE 是低速外部時鐘,接頻率為 32.768kHz 的石英晶體。這個主要是 RTC 的時鐘源。
  • HSE 是高速外部時鐘,可接石英/陶瓷諧振器,或者接外部時鐘源,頻率范圍為 4MHz~26MHz。我們的開發板接的是 8M 的晶振。HSE 也可以直接做為系統時鐘或者 PLL 輸入。
  • HSI 是高速內部時鐘,RC 振蕩器,頻率為 16MHz。可以直接作為系統時鐘或者用作 PLL
    輸入。
  • PLL 為鎖相環倍頻輸出。STM32F4 有兩個 PLL:
    • 主 PLL(PLL)由 HSE 或者 HSI 提供時鐘信號,并具有兩個不同的輸出時鐘。
      第一個輸出 PLLP 用于生成高速的系統時鐘(最高 168MHz)
      第二個輸出 PLLQ 用于生成 USB OTG FS 的時鐘(48MHz),隨機數發生器的時鐘和 SDIO
      時鐘。
    • 專用 PLL(PLLI2S)用于生成精確時鐘,從而在 I2S 接口實現高品質音頻性能。
  • 其余細節部分請查看文檔

    STM32F4 時鐘初始化配置

    STM32F4 時鐘系統初始化是在 system_stm32f4xx.c中的 SystemInit()函數中完成的。
    對于系統時鐘關鍵寄存器設置主要是在SystemInit函數中調用 SetSysClock()函數來設置的。
    在設置完相關寄存器后,接下來 SystemInit 函數內部會調用 SetSysClock函數。

    在配置的時候,特別需要注意的地方,就是我們還要同步修改 stm32f4xx.h 中宏定義標識符HSE_VALUE 的值為我們的外部時鐘:

    #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */#endif /* HSE_VALUE */

    這里默認固件庫配置的是 25000000,我們外部時鐘為 8MHz,所以我們根據我們硬件情況修改為 8000000 即可。
    那么 SystemInit 函數是怎么被系統調用的呢?
    SystemInit 是整個設置系統時鐘的入口函數。這個函數對于我們使用 ST提供的 STM32F4 固件庫的話,會在系統啟動之后先執行 main 函數,然后再接著執行 SystemInit 函數實現系統相關時鐘的設置。
    這個過程設置是在啟動文件 startup_stm32f40_41xxx.s 中間設置的,我們接下來看看啟動文件中這段啟動代碼:

    ; Reset handler Reset_Handler PROCEXPORT Reset_Handler [WEAK]IMPORT SystemInitIMPORT __mainLDR R0, =SystemInitBLX R0LDR R0, =__mainBX R0ENDP

    這段代碼的作用是在系統復位之后引導進入 main 函數,同時在進入 main 函數之前,首先要調用 SystemInit 系統初始化函數完成系統時鐘等相關配置。
    最后我們總結一下 SystemInit()函數中設置的系統時鐘大小:

    SYSCLK(系統時鐘) =168MHz AHB 總線時鐘(HCLK=SYSCLK) =168MHz APB1 總線時鐘(PCLK1=SYSCLK/4) =42MHz APB2 總線時鐘(PCLK2=SYSCLK/2) =84MHz PLL 主時鐘 =168MH

    這部分內容十分復雜,對模電和數電的知識儲備有要求,內容很多就不再貼出來。

    STM32F4 時鐘使能和配置

    上一部分,說明了系統復位之后調用 SystemInit 函數之后相關時鐘的默認配置。
    如果在系統初始化之后,我們還需要修改某些時鐘源配置,或者我們要使能相關外設的時鐘該怎么設置呢?這些設置實際是在 RCC 相關寄存器中配置的。因為 RCC 相關寄存器非常多,有興趣的同學可以直接打開《STM32F4 中文參考手冊》6.3 小節查看所有 RCC 相關寄存器的配置。
    所以這里我們不直接講解寄存器配置,而是通過 STM32F4 標準固件庫配置方法給大家講解。
    在 STM32F4 標準固件庫里,時鐘源的選擇以及時鐘使能等函數都是在 RCC 相關固件庫文件 stm32f4xx_rcc.h 和 stm32f4xx_rcc.c 中聲明和定義的。大家打開 stm32f4xx_rcc.h 文件可以看到文件開頭有很多宏定義標識符,然后是一系列時鐘配置和時鐘使能函數申明。這些函數大致可以歸結為三類,一類是外設時鐘使能函數,一類是時鐘源和分頻因子配置函數,還有一類是外設復位函數。當然還有幾個獲取時鐘源配置的函數。
    下面我們以幾種常見的操作來簡要介紹一下這些庫函數的使用。

    時鐘使能函數

    首先是時鐘使能函數。時鐘使能相關函數包括外設設置使能和時鐘源使能兩類。首先我們來看看外設時鐘使能相關的函數:

    void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

    這里主要有 5 個外設時鐘使能函數。5 個函數分別用來使能 5 個總線下面掛載的外設時鐘,這些總線分別為:AHB1 總線,AHB2 總線,AHB3 總線,APB1 總線以及 APB2 總線。要使能某個外設,調用對應的總線外設時鐘使能函數即可。
    這里我們要特別說明一下,STM32F4 的外設在使用之前,必須對時鐘進行使能,如果沒有使能時鐘,那么外設是無法正常工作的。對于哪個外設是掛載在哪個總線之下,雖然我們也可以查手冊查詢到,但是這里如果大家使用的是庫函數的話,實際上是沒有必要去查詢手冊的,這里我們給大家介紹一個小技巧。
    如何查看?
    比如我們要使能 GPIOA,我們只需要在 stm32f4xx_rcc.h 頭文件里面搜索 GPIOA,就可以搜索到對應的時鐘使能函數的第一個入口參數為 RCC_AHB1Periph_GPIOA,從這個宏定義標識符一眼就可以看出,GPIOA 是掛載在 AHB1 下面。
    同理,對于串口 1 我們可以搜索 USART1,找到標識符為 RCC_APB2Periph_USART1,那么很容易知道串口 1 是掛載在 APB2 之下。
    如何調用?
    如果我們要使能 GPIOA,那么我們可以在頭文件 stm32f4xx_rcc.h 里面查看到宏定義標識符 RCC_AHB1Periph_GPIOA,顧名思義 GPIOA是掛載在 AHB1 總線之下,所以,我們調用 AHB1 總線下外設時鐘使能函數 RCC_AHB1PeriphClockCmd 即可。
    -具體調用方式入如下:

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能 GPIOA 時鐘

    同理,如果我們要使能串口 1 的時鐘,那么我們調用的函數為:

    void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);

    具體的調用方法是:

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

    還有一類時鐘使能函數是時鐘源使能函數,前面已經講解過 STM32F4 有 5 大類時鐘源。
    這里我們列出來幾種重要的時鐘源使能函數:

    void RCC_HSICmd(FunctionalState NewState); void RCC_LSICmd(FunctionalState NewState); void RCC_PLLCmd(FunctionalState NewState); void RCC_PLLI2SCmd(FunctionalState NewState); void RCC_PLLSAICmd(FunctionalState NewState); void RCC_RTCCLKCmd(FunctionalState NewState);

    這些函數是用來使能相應的時鐘源。比如我們要使能 PLL 時鐘,那么調用的函數為:

    void RCC_PLLCmd(FunctionalState NewState);

    具體調用方法如下:

    RCC_PLLCmd(ENABLE);

    我們要使能相應的時鐘源,調用對應的函數即可。

    時鐘功能函數

    接下來我們要講解的是第二類時鐘功能函數:時鐘源選擇和分頻因子配置函數。這些函數是用來選擇相應的時鐘源以及配置相應的時鐘分頻系數。
    比如我們之前講解過系統時鐘SYSCLK,我們可以選擇 HSI,HSE 以及 PLL三個中的一個時鐘源為系統時鐘。那么到底選擇哪一個,這是可以配置的。下面我們列舉幾種時鐘源配置函數:

    void RCC_LSEConfig(uint8_t RCC_LSE); void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource); void RCC_HCLKConfig(uint32_t RCC_SYSCLK); void RCC_PCLK1Config(uint32_t RCC_HCLK); void RCC_PCLK2Config(uint32_t RCC_HCLK); void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource); void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ);

    比如我們要設置系統時鐘源為 HSI,那么我們可以調用系統時鐘源配置函數:

    void RCC_HCLKConfig(uint32_t RCC_SYSCLK);

    具體配置方法如下:

    RCC_HCLKConfig(RCC_SYSCLKSource_HSI);//配置時鐘源為 HSI

    又如我們要設置 APB1 總線時鐘為 HCLK 的 2 分頻,也就是設置分頻因子為 2 分頻,那么如果我們要使能 HSI,那么調用的函數為:

    void RCC_PCLK1Config(uint32_t RCC_HCLK);

    具體配置方法如下:

    RCC_PCLK1Config(RCC_HCLK_Div2);

    外設復位函數

    接下來我們看看第三類外設復位函數。如下:

    void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

    這類函數跟前面講解的外設時鐘函數使用方法基本一致,不同的是一個是用來使能外設時鐘,一個是用來復位對應的外設。這里大家在調用函數的時候一定不要混淆。
    對于這些時鐘操作函數,我們就不一一列舉出來,大家可以打開 RCC 對應的文件仔細了解。

    總結

    總線與時鐘部分讓人頭大,草草的過了一遍知識點,有點囫圇吞棗的意思了,不過我的目標也是先用起來,暫時不深究,等用到了之后再仔細學習相應的部分,未完待續 =w=

    總結

    以上是生活随笔為你收集整理的STM32学习之总线与时钟的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。