其實時鐘的配置一點也不難,只要看懂時鐘樹就好。
工程的里面startup_stm32l1xx_md.s為啟動文件,
; Reset handler routine
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit // 在stm32的其實代碼中SystemInit為系統(tǒng)調用的時鐘函數
BLX R0
LDR R0, =__main
BX R0
ENDP
打開system_stm32l1xx.c的 SystemInit 函數,此函數為系統(tǒng)時鐘初始化函數,沒有時鐘芯片是無法工作的。
void SystemInit (void)
{
/*!< Set MSION bit */
RCC->CR |= (uint32_t)0x00000100;
/*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */
RCC->CFGR &= (uint32_t)0x88FFC00C;
/*!< Reset HSION, HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xEEFEFFFE;
/*!< Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */
RCC->CFGR &= (uint32_t)0xFF02FFFF;
/*!< Disable all interrupts */
RCC->CIR = 0x00000000;
/*!< Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/*!< Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock(); // 關鍵在于此函數
}
打開 system_stm32l1xx.c 文件中的 SetSysClock 函數,打開此函數就會看到時鐘相關的配置,一般 system_stm32l1xx.c 文件的前面會有宏定義,只需注釋或打開對應的宏定義即可, SetSysClock 函數就會調用對應的時鐘配置函數。(如果想要自己配置時鐘頻率,則要修改對應時鐘樹的倍頻和分頻參數)
//#define SYSCLK_FREQ_MSI
#ifndef SYSCLK_FREQ_MSI
#define SYSCLK_FREQ_HSI HSI_VALUE
// #define SYSCLK_FREQ_HSE HSE_VALUE
/* #define SYSCLK_FREQ_4MHz 4000000 */
/* #define SYSCLK_FREQ_8MHz 8000000 */
/* #define SYSCLK_FREQ_16MHz 16000000 */
//#define SYSCLK_FREQ_32MHz 32000000
#else
/* #define SYSCLK_FREQ_MSI_64KHz 64000 */
/* #define SYSCLK_FREQ_MSI_128KHz 128000 */
/* #define SYSCLK_FREQ_MSI_256KHz 256000 */
/* #define SYSCLK_FREQ_MSI_512KHz 512000 */
/* #define SYSCLK_FREQ_MSI_1MHz 1000000 */
/* #define SYSCLK_FREQ_MSI_2MHz 2000000 */
// #define SYSCLK_FREQ_MSI_4MHz 4000000
#endif
從圖中可知:共有5 種時鐘源,分別為
HSE:外部8M晶振)、
HSI: 內部高速晶振16MHz
LSI:內部低速晶振37khz
LSE: 外部低速晶振 32.768khz
MSI: 內部多速度段晶振,65.536khz、131.072khz、262.144khz、524.288khz、1.048MHz、
2.097MHz、4.194MHz (默認 2.097MHz)
查看系統(tǒng)時鐘源
sysclk_source = RCC_GetSYSCLKSource();
printf("默認系統(tǒng)時鐘源: %d\r\n", sysclk_source);
查看各個時鐘的頻率
void get_sys_clock_fre(void)
{
RCC_ClocksTypeDef get_rcc_clock;
/* 獲取系統(tǒng)時鐘 */
RCC_GetClocksFreq(&get_rcc_clock);
/* 輸出 系統(tǒng)時鐘頻率 */
printf(" SYSCLK %d\r\n", get_rcc_clock.SYSCLK_Frequency);
printf(" HCLK %d\r\n" , get_rcc_clock.HCLK_Frequency);
printf(" PCLK1 %d\r\n" , get_rcc_clock.PCLK1_Frequency);
printf(" PCLK2 %d\r\n" , get_rcc_clock.PCLK2_Frequency);
}