此文档主要介绍如何修改STM32L151系列的标准库的时钟晶振
1.背景介绍
因为STM32的标准库函数中默认使用的外部8M的高速晶振,但是在实际的开发阶段,可以使用的不是8M的外部晶振。所以此时需要对标准库函数做出相应的修改,外部晶振才可以起振。本文档将使用12M的外部高速晶振为例,来大致的了解如何修改标准库函数,使其调用外部的12M高速晶振。
2.主要步骤
第一步:需要了解时钟函数是在什么地方调用的,打开startup_stm32l1xx_md.s
Reset handler routine
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit //***在stm32的其实代码中SystemInit为系统调用的时钟函数***
BLX R0
LDR R0, =__main
BX R0
ENDP
第二步:了解初始化函数具体在哪里调用外部高速晶振的,打开system_stm32l1xx.c的SystemInit函数
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;
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
/* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */
SetSysClock(); //***此函数的作用初始化外部高速晶振,如果注释此函数,此系统会默认使用STM32内部8M的高速晶振***
#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
}
第三步 修改外部8M的高速晶振------->12M,打开 stm32l1xx.h
/**
* @brief In the following line adjust the value of External High Speed oscillator (HSE)
used in your application
Tip: To avoid modifying this file each time you need to use different HSE, you
can define the HSE value in your toolchain compiler preprocessor.
*/
#if !defined (HSE_VALUE)
//***此行代码是8M的外部高速晶振,所以注释掉此行代码***
//#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
//***将原来的8M外部高速晶振换为12M的外部高速晶振***
#define HSE_VALUE ((uint32_t)12000000) /*!< Value of the External oscillator in Hz */
#endif
第四步 修改时钟的倍频与分频系数,打开system_stm32l1xx.c的SetSysClock函数
/* PLL configuration */ //***为PLL的配置***
#if 0
/*default HSE 8M*/
//因为STM32l151的最大时钟频率为32M,外部的采用的8M的高速晶振,所以经过2分频,8倍频。
//8M / 2 * 8 == 32M
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL |
RCC_CFGR_PLLDIV));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL8 | RCC_CFGR_PLLDIV2);
#else
/*HSE 12M*/
//因为实际情况使用的12M的外部高速晶振,所以采用3分频,8倍频。故为12M / 3 * 8 == 32M
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL |
RCC_CFGR_PLLDIV));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL8 | RCC_CFGR_PLLDIV3);
#endif
经过这四步之后,标准库函数已经改为了默认使用外部12M高速晶振工作。具体情况可以使用示波器进行验证,在此不多余介绍。