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;
功能講解
下面我們具體講解一下圖中幾個總線的知識。
此總線用于將 Cortex-M4 內核的指令總線連接到總線矩陣。內核通過此總線獲取指令。此總線訪問的對象是包括代碼的存儲器。
此總線用于將 Cortex-M4 數據總線和 64KB CCM 數據 RAM 連接到總線矩陣。內核通過此總線進行立即數加載和調試訪問。
此總線用于將 Cortex-M4 內核的系統總線連接到總線矩陣。此總線用于訪問位于外設或 SRAM 中的數據。
此總線用于將 DMA 存儲器總線主接口連接到總線矩陣。DMA 通過此總線來執行存儲器數據的傳入和傳出。
此總線用于將 DMA 外設主總線接口連接到總線矩陣。DMA 通過此總線訪問 AHB 外設或執行存儲器之間的數據傳輸。
此總線用于將以太網 DMA 主接口連接到總線矩陣。以太網 DMA通過此總線向存儲器存取數據。
此總線用于將 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 是外部時鐘源,其他的是內部時鐘源。
功能講解
輸入。
- 主 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 中間設置的,我們接下來看看啟動文件中這段啟動代碼:
這段代碼的作用是在系統復位之后引導進入 main 函數,同時在進入 main 函數之前,首先要調用 SystemInit 系統初始化函數完成系統時鐘等相關配置。
最后我們總結一下 SystemInit()函數中設置的系統時鐘大小:
這部分內容十分復雜,對模電和數電的知識儲備有要求,內容很多就不再貼出來。
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 即可。
-具體調用方式入如下:
同理,如果我們要使能串口 1 的時鐘,那么我們調用的函數為:
void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);具體的調用方法是:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);還有一類時鐘使能函數是時鐘源使能函數,前面已經講解過 STM32F4 有 5 大類時鐘源。
這里我們列出來幾種重要的時鐘源使能函數:
這些函數是用來使能相應的時鐘源。比如我們要使能 PLL 時鐘,那么調用的函數為:
void RCC_PLLCmd(FunctionalState NewState);具體調用方法如下:
RCC_PLLCmd(ENABLE);我們要使能相應的時鐘源,調用對應的函數即可。
時鐘功能函數
接下來我們要講解的是第二類時鐘功能函數:時鐘源選擇和分頻因子配置函數。這些函數是用來選擇相應的時鐘源以及配置相應的時鐘分頻系數。
比如我們之前講解過系統時鐘SYSCLK,我們可以選擇 HSI,HSE 以及 PLL三個中的一個時鐘源為系統時鐘。那么到底選擇哪一個,這是可以配置的。下面我們列舉幾種時鐘源配置函數:
比如我們要設置系統時鐘源為 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学习之总线与时钟的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员之常用软件安装过程记录
- 下一篇: WAMP本地环境配置多站点虚拟目录教程(