LinkedInSTM32F4 時鐘系統(tǒng)初始化是在system_stm32f4xx.c中的 SystemInit()函數(shù)中完成的。 對于系統(tǒng)時鐘關(guān)鍵寄存器設(shè)置主要是在 SystemInit 函數(shù)中調(diào)用 SetSysClock()函數(shù)來設(shè)置的。我們可以先看看 SystemInit ()函數(shù)體:
void SystemInit(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB-》CPACR |= ((3UL 《《 10*2)|(3UL 《《 11*2));
#endif
RCC-》CR |= (uint32_t)0x00000001;
RCC-》CFGR = 0x00000000;
RCC-》CR &= (uint32_t)0xFEF6FFFF;
RCC-》PLLCFGR = 0x24003010;
RCC-》CR &= (uint32_t)0xFFFBFFFF;
RCC-》CIR = 0x00000000;
#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
SystemInit_ExtMemCtl();
#endif
SetSysClock();
#ifdef VECT_TAB_SRAM
SCB-》VTOR = SRAM_BASE | VECT_TAB_OFFSET;
#else
SCB-》VTOR = FLASH_BASE | VECT_TAB_OFFSET;
#endif
}
SystemInit函數(shù)開始先進行浮點運算單元設(shè)置,然后是復(fù)位PLLCFGR,CFGR寄存器,同時通過設(shè)置 CR 寄存器的 HSI 時鐘使能位來打開 HSI 時鐘。默認情況下如果 CFGR 寄存器復(fù)位,那么是選擇HSI作為系統(tǒng)時鐘,這點大家可以查看RCC-》CFGR 寄存器的位描述最低2位可以得知,當(dāng)?shù)蛢晌慌渲脼?00的時候(復(fù)位之后),會選擇 HSI振蕩器為系統(tǒng)時鐘。也就是說,調(diào)用 SystemInit 函數(shù)之后,首先是選擇 HSI 作為系統(tǒng)時鐘。
在設(shè)置完相關(guān)寄存器后,接下來SystemInit函數(shù)內(nèi)部會調(diào)用 SetSysClock函數(shù)。這個函數(shù)比較長,我們就把函數(shù)一些關(guān)鍵代碼行截取出來給大家講解一下。這里我們省略一些宏定義標識符值的判斷而直接把針對STM32F407 比較重要的內(nèi)容貼出來:
static void SetSysClock(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
RCC-》CR |= ((uint32_t)RCC_CR_HSEON);
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;
}
if (HSEStatus == (uint32_t)0x01)
{
RCC-》APB1ENR |= RCC_APB1ENR_PWREN;
PWR-》CR |= PWR_CR_VOS;
RCC-》CFGR |= RCC_CFGR_HPRE_DIV1;
RCC-》CFGR |= RCC_CFGR_PPRE2_DIV2;
RCC-》CFGR |= RCC_CFGR_PPRE1_DIV4;
RCC-》CFGR |= RCC_CFGR_PPRE2_DIV1;
RCC-》CFGR |= RCC_CFGR_PPRE1_DIV2;
RCC-》PLLCFGR = PLL_M | (PLL_N 《《 6) | (((PLL_P 》》 1) -1) 《《 16) |
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q 《《 24);
RCC-》CR |= RCC_CR_PLLON;
while((RCC-》CR & RCC_CR_PLLRDY) == 0)
{
}
FLASH-》ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN
|FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
RCC-》CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC-》CFGR |= RCC_CFGR_SW_PLL;
while ((RCC-》CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
{
}
}
else
{
}
}
這段代碼的大致流程是這樣的:先使能外部時鐘 HSE,等待 HSE 穩(wěn)定之后,配置AHB,APB1,APB2 時鐘相關(guān)的分頻因子,也就是相關(guān)外設(shè)的時鐘。等待這些都配置完成之后,打開主PLL時鐘,然后設(shè)置主PLL作為系統(tǒng)時鐘 SYSCLK時鐘源。如果HSE 不能達到就緒狀態(tài)(比如外部晶振不能穩(wěn)定或者沒有外部晶振),那么依然會是HSI作為系統(tǒng)時鐘。
在這里要特別提出來,在設(shè)置主PLL時鐘的時候,會要設(shè)置一系列的分頻系數(shù)和倍頻系數(shù)參數(shù)。大家可以從SetSysClock函數(shù)的這行代碼看出:
RCC-》PLLCFGR = PLL_M | (PLL_N 《《 6) | (((PLL_P 》》 1) -1) 《《 16) |
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q 《《 24);
這些參數(shù)是通過宏定義標識符的值來設(shè)置的。默認的配置在 System_stm32f4xx.c 文件開頭的地方配置。對于我們開發(fā)板,我們的設(shè)置參數(shù)值如下:
#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
在開發(fā)過程中,我們可以通過調(diào)整這些值來設(shè)置我們的系統(tǒng)時鐘。
這里還有個特別需要注意的地方,就是我們還要同步修改 stm32f4xx.h 中宏定義標識符HSE_VALUE 的值為我們的外部時鐘:
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000)
#endif
這里默認固件庫配置的是25000000,我們外部時鐘為8MHz,所以我們根據(jù)我們硬件情況修改為8000000即可。
講到這里,大家對 SystemInit 函數(shù)的流程會有個比較清晰的理解。那么 SystemInit 函數(shù)是怎么被系統(tǒng)調(diào)用的呢?SystemInit是整個設(shè)置系統(tǒng)時鐘的入口函數(shù)。這個函數(shù)對于我們使用ST提供的 STM32F4 固件庫的話,會在系統(tǒng)啟動之后先執(zhí)行main函數(shù),然后再接著執(zhí)行SystemInit函數(shù)實現(xiàn)系統(tǒng)相關(guān)時鐘的設(shè)置。這個過程設(shè)置是在啟動文件 startup_stm32f40_41xxx.s中間設(shè)置的,我們接下來看看啟動文件中這段啟動代碼:
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
這段代碼的作用是在系統(tǒng)復(fù)位之后引導(dǎo)進入main函數(shù),同時在進入main函數(shù)之前,首先
要調(diào)用 SystemInit系統(tǒng)初始化函數(shù)完成系統(tǒng)時鐘等相關(guān)配置。
最后我們總結(jié)一下SystemInit()函數(shù)中設(shè)置的系統(tǒng)時鐘大小:
SYSCLK(系統(tǒng)時鐘) =168MHz
AHB總線時鐘(HCLK=SYSCLK) =168MHz
APB1總線時鐘(PCLK1=SYSCLK/4) =42MHz
APB2總線時鐘(PCLK2=SYSCLK/2) =84MHz
PLL主時鐘 =168MHz
上一篇:STM32單片機ADC的模擬看門狗的測試
下一篇:基于STM32四軸飛行器電路設(shè)計的詳細圖解資料概述
推薦閱讀最新更新時間:2025-05-12 22:55




設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- 人形機器人馬拉松背后的思考,兆易創(chuàng)新如何賦能機器人產(chǎn)業(yè)
- 一種基于STM32的智能柜控制器設(shè)計
- 小型傾轉(zhuǎn)旋翼機的無刷直流電機驅(qū)動器設(shè)計
- 超高速攝影機電控系統(tǒng)設(shè)計
- 基于GPS自動授時的無線智能控制器的設(shè)計
- 基于PTR2000的無線氣象信息采集系統(tǒng)設(shè)計
- Microchip推出MEC175xB系列器件,為嵌入式控制器引入硬件 抗量子攻擊能力
- 無人飛行器機載穩(wěn)定云臺控制系統(tǒng)的設(shè)計
- 匠芯創(chuàng)推出面向具身智能高性能實時處理器M7000
- BD9851EFV升壓/反相轉(zhuǎn)換器典型應(yīng)用電路
- EVB-LIV3F、Teseo-LIV3F GNSS 模塊評估板
- PD70101EVB6FC、基于 PD70101 的 IEEE802.3 Type 1 PD 評估板控制 5V/1.2A 輸出隔離反激轉(zhuǎn)換器以實現(xiàn)最小 PSE 功耗
- EVAL-AD5204SDZ,用于 AD5204 四通道、256 位、數(shù)字電位器的評估板
- 使用 Analog Devices 的 LT1109CS8 的參考設(shè)計
- LTC3632EDD 高效 15V、4mA 穩(wěn)壓器的典型應(yīng)用電路
- TC78B016FTG 三相無刷直流電機驅(qū)動器評估板
- LT6657BHMS8-2.5 低噪聲統(tǒng)計平均基準的典型應(yīng)用電路
- LTC1729CMS8-8.4 演示板,LT1510-5CGN 終端控制器/鋰離子電池充電器,11.5V 至 28V 輸入,8.4Vout @ 1A Max
- TJA1128EVB: TJA1128 LIN迷你系統(tǒng)基礎(chǔ)芯片評估板