STM32中的時鐘系統概述

5個藍色背景的是時鐘源
SYSCLK是系統時鐘,最重要的時鐘,可以看到其他的外設的時鐘都來源于系統時鐘
HSI RC高速内部
約為8MHz,但不太穩定,可以作為系統時鐘,灰色背景的梯形表示選擇器
HSE Os高速外部
接晶振,例如8MHz,其可以直接作為選擇器的輸入,也可以分頻後作為選擇器輸入,PLL表示鎖相環,用于倍頻,可以選擇2-16,通過鎖相環寄存器配置,産生的時鐘為PLL_CLK
CSS時鐘監控系統
一旦HSE失效,則自動切換到SYSCLK=HSI
LSE Os低速的外部時鐘
通過外接晶振産生,一般為32.768kHz,用于RTCCLK
RTCCLK還可以來自于HSE的128分頻
LSI RC低速内部
由内部的RC振蕩器産生,約為40kHz
主要是用于STM32的獨立watch dog提供時鐘
MCO輸出内部時鐘引腳PA8
可以來自于系統時鐘SYSCLK
可以來自于HSI
可以來自于HSE
可以來自于PLLCLK的2分頻
USB時鐘
48MHz,可以來自于PLL時鐘經過USB分頻器,除以1或者1.5
72MHz和48MHz之間的倍數就是1.5
AHB Prescaler AHB預分頻器
AHB預分頻器的分頻因子有9種選擇:
1,2,4,8,16,64,128,256,512
分頻後産生HCLK這個時鐘最高可以到72MHz
APB1 Prescale APB1預分頻器
産生PCLK1,用于挂低速外設,例如通用定時器
APB2 Prescale APB2預分頻器
産生PCLK2,可以供對于時鐘要求高的外設
注意:任何一個外設使用前,必須首先使能其相應的時鐘
stm32中的時鐘配置RCC
如下圖所示,為STM32工程中對于時鐘的配置檔案
首先打開寄存器位址名稱映射頭檔案
這個頭檔案中對于大部分寄存器的映射都會在這裡通過一個結構體來定義
如下圖所示,這個結構體中的成員變量映射了對應的寄存器
對于RCC寄存器的較長的描述,可以參考STM32中文參考手冊
RCC時鐘控制寄存器
HSI,HSE,LSI,LSE,PLL這5個時鐘源,使用前需要使能,使能後還不穩定,穩定後會産生穩定标志位
RCC時鐘配置寄存CFGR
配置選擇器,PLL倍頻系數,Scaler的分頻系數
RCC外設時鐘使能寄存器
AHBENR AHB外設時鐘使能寄存器
包括SDIO,FSMC,CRC,FLITF,SRAM,DMA1,DMA2
APB2ENR APB2外設時鐘使能寄存器
包括ADC3,USART1,TIM8,SIP1,TIM1,ADC2,ADC1,IO ABCDEFG等
APB1ENR APB1外設時鐘使能寄存器
包括DAC接口,電源接口,備份接口,CAN時鐘,USB時鐘,I2C時鐘,UART2345時鐘,SPI23時鐘,看門狗時鐘,Timer 234567時鐘等
RCC寄存器的操作
可以通過相關的庫函數,對于這些RCC寄存器進行操作
這些庫函數可以分為以下幾類:
時鐘使能配置
void RCC_LSEConfig(uint8_t RCC_LSE);
void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
void RCC_HSEConfig(uint32_t RCC_HSE);
void RCC_HSICmd(FunctionalState NewState);
void RCC_LSICmd(FunctionalState NewState);
...
時鐘來源配置
void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul);
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);
分頻系數選擇配置
void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
void RCC_PCLK1Config(uint32_t RCC_HCLK);
void RCC_PCLK2Config(uint32_t RCC_HCLK);
外設時鐘使能
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
其他外設時鐘配置
void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource);
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);
狀态參數擷取
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks);
uint8_t RCC_GetSYSCLKSource(void);
FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG);
RCC中斷