tft每日頭條

 > 圖文

 > stm32芯片使用心得

stm32芯片使用心得

圖文 更新时间:2024-09-06 00:22:07

文檔是本人學結的文檔,有些亂,勿怪。

1、STM32F407時鐘系統

stm32芯片使用心得(STM32F4芯片嵌入式學習7)1

在 STM32F4 中,有 5 個最重要的時鐘源,為 HSI、HSE、LSI、LSE、PLL。其中 PLL 實際是分為兩個時鐘源,分别為主 PLL 和專用 PLL。從時鐘頻率來分可以分為高速時鐘源和低速時鐘源,在這 5 個中 HSI,HSE 以及 PLL 是高速時鐘,LSI 和 LSE 是低速時鐘。從來源可分為外部時鐘源和内部時鐘源,外部時鐘源就是從外部通過接晶振的方式獲取時鐘源,其中 HSE 和LSE 是外部時鐘源,其他的是内部時鐘源。下面我們看看 STM32F4 的這 5 個時鐘源,我們講解順序是按圖中紅圈标示的順序:

①、LSI 是低速内部時鐘,RC 振蕩器,頻率為 32kHz 左右。供獨立看門狗和自動喚醒單元使用。

②、LSE 是低速外部時鐘,接頻率為 32.768kHz 的石英晶體。這個主要是 RTC 的時鐘源。

③、HSE 是高速外部時鐘,可接石英/陶瓷諧振器,或者接外部時鐘源,頻率範圍為 4MHz~26MHz。我們的開發闆接的是 8M 的晶振。HSE 也可以直接做為系統時鐘或者 PLL 輸入。

④、HSI 是高速内部時鐘,RC 振蕩器,頻率為 16MHz。可以直接作為系統時鐘或者用作 PLL輸入。

⑤、PLL 為鎖相環倍頻輸出。STM32F4 有兩個 PLL:

1) 主 PLL(PLL)由 HSE 或者 HSI 提供時鐘信号,并具有兩個不同的輸出時鐘。

第一個輸出 PLLP 用于生成高速的系統時鐘(最高 168MHz)

第二個輸出 PLLQ 用于生成 USB OTG FS 的時鐘(48MHz),随機數發生器的時鐘和 SDIO

時鐘。

2)專用 PLL(PLLI2S)用于生成精确時鐘,從而在 I2S 接口實現高品質音頻性能

這裡我們着重看看主 PLL 時鐘第一個高速時鐘輸出 PLLP 的計算方法。如圖

stm32芯片使用心得(STM32F4芯片嵌入式學習7)2

可以看出。主 PLL 時鐘的時鐘源要先經過一個分頻系數為 M 的分頻器,然後經過倍頻系數為 N 的倍頻器出來之後的時候還需要經過一個分頻系數為 P(第一個輸出 PLLP)或者 Q(第二個輸出 PLLQ)的分頻器分頻之後,最後才生成最終的主 PLL 時鐘。例如我們的外部晶振選擇 8MHz。同時我們設置相應的分頻器 M=8,倍頻器倍頻系數 N=336,分頻器分頻系數 P=2,那麼主 PLL 生成的第一個輸出高速時鐘 PLLP 為:

PLL=8MHz * N/ (M*P)=8MHz* 336 /(8*2) = 168MHz

如果我們選擇HSE為PLL時鐘源,同時SYSCLK時鐘源為PLL,那麼SYSCLK時鐘為 168MHz。這對于我們後面的實驗都是采用這樣的配置。上面我們簡要概括了 STM32 的時鐘源,那麼這 5 個時鐘源是怎麼給各個外設以及系統提供時鐘的呢?這裡我們選擇一些比較常用的時鐘知識來講解。圖1中

A.這裡是看門狗時鐘輸入。從圖中可以看出,看門狗時鐘源隻能是低速的 LSI 時鐘。

B.這裡是 RTC 時鐘源,從圖上可以看出,RTC 的時鐘源可以選擇 LSI,LSE,以及HSE 分頻後的時鐘,HSE 分頻系數為 2~31。

C.這裡是 STM32F4 輸出時鐘 MCO1 和 MCO2。MCO1 是向芯片的 PA8 引腳輸出時鐘。它有四個時鐘來源分别為:HSI,LSE,HSE 和 PLL 時鐘。MCO2 是向芯片的PC9 輸出時鐘,它同樣有四個時鐘來源分别為:HSE,PLL,SYSCLK 以及 PLLI2S時鐘。MCO 輸出時鐘頻率最大不超過 100MHz。

D.這裡是系統時鐘。從圖 可以看出,SYSCLK 系統時鐘來源有三個方面:HSI,HSE 和 PLL。在我們實際應用中,因為對時鐘速度要求都比較高我們才會選用 STM32F4 這種級别的處理器,所以一般情況下,都是采用 PLL 作為 SYSCLK時鐘源。根據前面的計算公式,大家就可以算出你的系統的 SYSCLK 是多少。

E.這裡我們指的是以太網 PTP 時鐘,AHB 時鐘,APB2 高速時鐘,APB1 低速時鐘。這些時鐘都是來源于 SYSCLK 系統時鐘。其中以太網 PTP 時鐘是使用系統時鐘。AHB,APB2 和 APB1 時鐘是經過 SYSCLK 時鐘分頻得來。這裡大家記住,AHB最大時鐘為168MHz, APB2高速時鐘最大頻率為84MHz,而APB1低速時鐘最大頻率為 42MHz。

F.這裡是指 I2S 時鐘源。從圖 4.3.1 可以看出,I2S 的時鐘源來源于 PLLI2S 或者映射到 I2S_CKIN 引腳的外部時鐘。I2S 出于音質的考慮,對時鐘精度要求很高。探索者 STM32F4 開發闆使用的是内部 PLLI2SCLK。

G.這是 STM32F4 内部以太網 MAC 時鐘的來源。對于 MII 接口來說,必須向外部PHY 芯片提供 25Mhz 的時鐘,這個時鐘,可以由 PHY 芯片外接晶振,或者使用STM32F4 的 MCO 輸出來提供。然後, PHY 芯片再給 STM32F4 提 供ETH_MII_TX_CLK 和 ETH_MII_RX_CLK 時鐘。對于 RMII 接口來說,外部必須提供 50Mhz 的時鐘驅動 PHY 和 STM32F4 的 ETH_RMII_REF_CLK,這個 50Mhz時鐘可以來自 PHY、有源晶振或者 STM32F4 的 MCO。我們的開發闆使用的是RMII 接口,使用 PHY 芯片提供 50Mhz 時鐘驅動 STM32F4 的ETH_RMII_REF_CLK。

H.這裡是指外部 PHY 提供的 USB OTG HS(60MHZ)時鐘。這裡還需要說明一下,Cortex 系統定時器 Systick 的時鐘源可以是 AHB 時鐘 HCLK 或HCLK 的 8 分頻。具體配置請參考 Systick 定時器配置,我們後面會在 5.1 小節講解 delay 文件夾代碼的時候講解。在以上的時鐘輸出中,有很多是帶使能控制的,例如 AHB 總線時鐘、内核時鐘、各種 APB1外設、APB2 外設等等。當需要使用某模塊時,記得一定要先使能對應的時鐘。後面我們講解實例的時候會講解到時鐘使能的方法。

2、STM32F4芯片時間系統使能、

上一小節我們對 STM32F4 時鐘樹進行了初步的講解,接下來我們來講解一下 STM32F4 的系統時鐘配置。STM32F4 時鐘系統初始化是在 system_stm32f4xx.c 中的 SystemInit()函數中完成的。對于系統時鐘關鍵寄存器設置主要是在 SystemInit 函數中調用 SetSysClock()函數來設置的。我們可以先看看 SystemInit ()函數體:

void SystemInit(void)

{

/* FPU settings ------------------------------------------------------------*/

#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)

SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */

#endif

/* Reset the RCC clock configuration to the default reset state ------------*/

/* Set HSION bit */

RCC->CR |= (uint32_t)0x00000001;

/* Reset CFGR register */

RCC->CFGR = 0x00000000;

/* Reset HSEON, CSSON and PLLON bits */

RCC->CR &= (uint32_t)0xFEF6FFFF;

/* Reset PLLCFGR register */

RCC->PLLCFGR = 0x24003010;

/* Reset HSEBYP bit */

RCC->CR &= (uint32_t)0xFFFBFFFF;

/* Disable all interrupts */

RCC->CIR = 0x00000000;

#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)

SystemInit_ExtMemCtl();

#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */

/* Configure the System clock source, PLL Multiplier and Divider factors,

AHB/APBx prescalers and Flash settings ----------------------------------*/

SetSysClock();

/* Configure the Vector Table location add offset address ------------------*/

#ifdef VECT_TAB_SRAM

SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */

#else

SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */

#endif

}

SystemInit 函數開始先進行浮點運算單元設置,然後是複位 PLLCFGR,CFGR 寄存器,同時通過設置 CR 寄存器的 HSI 時鐘使能位來打開 HSI 時鐘。默認情況下如果 CFGR 寄存器複位,那麼是選擇 HSI 作為系統時鐘,這點大家可以查看 RCC->CFGR 寄存器的位描述最低 2 位可以得知,當低兩位配置為 00 的時候(複位之後),會選擇 HSI 振蕩器為系統時鐘。也就是說,調用 SystemInit 函數之後,首先是選擇 HSI 作為系統時鐘。下面是 RCC->CFGR 寄存器的位 1:0配置描述(CFGR 寄存器詳細描述請參考《STM32F4 中文參考手冊》6.3.31CFGR 寄存器配置表)如下表

stm32芯片使用心得(STM32F4芯片嵌入式學習7)3

在設置完相關寄存器後,接下來 SystemInit 函數内部會調用 SetSysClock 函數。這個函數比較長,我們就把函數一些關鍵代碼行截取出來給大家講解一下。這裡我們省略一些宏定義标識符值的判斷而直接把針對 STM32F407 比較重要的内容貼出來:

stm32芯片使用心得(STM32F4芯片嵌入式學習7)4

stm32芯片使用心得(STM32F4芯片嵌入式學習7)5

這段代碼的大緻流程是這樣的:先使能外部時鐘 HSE,等待 HSE 穩定之後,配置AHB,APB1,APB2 時鐘相關的分頻因子,也就是相關外設的時鐘。等待這些都配置完成之後,打開主 PLL 時鐘,然後設置主 PLL 作為系統時鐘 SYSCLK 時鐘源。如果 HSE 不能達到就緒狀态(比如外部晶振不能穩定或者沒有外部晶振),那麼依然會是 HSI 作為系統時鐘。在這裡要特别提出來,在設置主 PLL 時鐘的時候,會要設置一系列的分頻系數和倍頻系數參數。大家可以從 SetSysClock 函數的這行代碼看出:

RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |

(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

這些參數是通過宏定義标識符的值來設置的。默認的配置在 System_stm32f4xx.c 文件開頭的地方配置。對于我們開發闆,我們的設置參數值如下:

#define PLL_M 8

#define PLL_Q 7

#define PLL_N 336

#define PLL_P 2

所以我們的主 PLL 時鐘為:

PLL=8MHz * N/ (M*P)=8MHz* 336 /(8*2) = 168MHz

在開發過程中,我們可以通過調整這些值來設置我們的系統時鐘。這裡還有個特别需要注意的地方,就是我們還要同步修改 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 函數是怎麼被系統調用的呢?SystemInit 是整個設置系統時鐘的入口函數。這個函數對于我們使用 ST提供的 STM32F4 固件庫的話,會在系統啟動之後先執行 main 函數,然後再接着執行 SystemInit函數實現系統相關時鐘的設置。這個過程設置是在啟動文件 startup_stm32f40_41xxx.s 中間設置的,我們接下來看看啟動文件中這段啟動代碼:

; Reset handler

Reset_Handler PROC

EXPORT Reset_Handler [WEAK]

IMPORT SystemInit

IMPORT __main

LDR R0, =SystemInit

BLX R0

LDR R0, =__main

BX R0

ENDP

這段代碼的作用是在系統複位之後引導進入 main 函數,同時在進入 main 函數之前,首先要調用 SystemInit 系統初始化函數完成系統時鐘等相關配置。

最後我們總結一下 SystemInit()函數中設置的系統時鐘大小:

SYSCLK(系統時鐘) =168MHz

AHB 總線時鐘(HCLK=SYSCLK)

=168MHz

APB1 總線時鐘(PCLK1=SYSCLK/4) =42MHz

APB2 總線時鐘(PCLK2=SYSCLK/2) =84MHz

PLL 主時鐘

=168MHz

ARM 指令集中的跳轉指令可以完成從當前指令向前或向後的 32MB 的地址空間的跳轉,包括以下 4 條指令:

(1) B 跳轉指令

(2) BL 帶返回的跳轉指令

(3) BLX 帶返回和狀态切換的跳轉指令

(4) BX 帶狀态切換的跳轉指令

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关圖文资讯推荐

热门圖文资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved