#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
#define SYSCLK_FREQ_24MHz 24000000
#else
#define SYSCLK_FREQ_36MHz 36000000// 选择系统工作频率为36MHz
#endif
注意在V3.5.0以上的库文件里SystemInit()函数已经被添加入启动文件中了,也就是库已经自动配置好了 HCLK(AHB总线)、PLCK1(APB1)、PLCK2(APB2)这几个总线的时钟频率,一般在36MHz以下的工作频率 HCLK=PLCK1=PLCK2=用户选择的工作频率,在超过36MHz的工作频率HCLK=PLCK2=用户选择的频率,而PCKL1因为是低速总线最大只能到36MHz,所以库自动设置PCLK=36MHz。
在V3.5.0以下的库中,通常在自己写的时钟配置使能函数里加入SystemInit(),比如我自己用的RCC_Configuration(void)如下:
void RCC_Configuration(void)
{
SystemInit();//初始化系统时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div4); //设置ADC
的工作频率为9M
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3| RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA |RCC_APB2Periph_AFIO, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_ClockSecuritySystemCmd(ENABLE);
}
我已经定义了STM32F10X_CL,SYSCLK_FREQ_72MHz
函数调用顺序:
startup_stm32f10x_cl.s(启动文件) → SystemInit()
→
初始化时钟用到的RCC寄存器复位值:
RCC_CR = 0x0000 xx83; RCC_CFGR = 0x0000 0000;RCC_CIR = 0x0000 0000; RCC_CFGR2 = 0x0000 0000;
SystemInit()
在调用 SetSysClock()之前RCC寄存器的值如下(都是一些与运算,或运算,在此就不赘述了):
RCC->CR = 0x0000
0083;
SetSysClock()函数如下:
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
#elif defined SYSCLK_FREQ_24MHz
#elif defined SYSCLK_FREQ_36MHz
#elif defined SYSCLK_FREQ_48MHz
#elif defined SYSCLK_FREQ_56MHz
#elif defined SYSCLK_FREQ_72MHz //我的定义的是SYSCLK_FREQ_72MHz,所以调用SetSysClockTo72()
#endif
}
SetSysClockTo72()函数如下:
static void SetSysClockTo72(void)
{
#ifdef STM32F10X_CL
#else
#endif
}
1:AHB, APB1,APB2时钟确定
//HCLK = SYSCLK ,从下面的分析可以得出SYSCLK是使用PLLCLK时钟的,也就是72MHZ(至于72MHZ如何得来,请看下面分析)
2:如何得出SYSCLK(系统时钟)为72MHZ(外部晶振25MHZ)
//记得参考英文芯片资料的时钟树P115页和RCC时钟寄存器进行理解
RCC->CFGR2 = (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 RCC_CFGR2_PLL2MUL8 RCC_CFGR2_PREDIV1SRC_PLL2 RCC_CFGR2_PREDIV1_DIV5);
RCC_CFGR2_PREDIV2_DIV5:
RCC_CFGR2_PLL2MUL8
RCC_CFGR2_PREDIV1SRC_PLL2 : RCC_CFGR2的第16位为1,选择PLL2CLK 作为PREDIV1的时钟源
RCC_CFGR2_PREDIV1_DIV5:PREDIV1 = 5;PREDIV1对输入时钟5分频 PREDIV1CLK = PLL2CLK / 5 = 8MHZ
以上是对RCC_CFGR2进行的配置
--------------------------------------------------------------------------------------
RCC->CFGR = (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1
RCC_CFGR_PLLSRC_PREDIV1
RCC_CFGR_PLLXTPRE_PREDIV1
:操作的是RCC_CFGR的第17位PLLXTPRE,操作这一位和操作RCC_CFGR2寄存器的位[3:0]中的最低位是相同的效果
RCC_CFGR_PLLSRC_PREDIV1 :选择PREDIV1输出作为PLL输入时钟;PREDIV1CLK = 8MHZ,所以输入给PLL倍频的 时钟源是8MHZ
RCC_CFGR_PLLMULL9 :PLLMUL = 9;PLL倍频系数为9,也就是对 PLLCLK = PREDIV1CLK * 8 = 72MHZ
以上是对RCC_CFGR进行的配置
---------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
至此基本配置已经完成,配置的时钟如下所述:
SYSCLK(系统时钟) = 72MHZ
AHB总线时钟
APB1总线时钟
APB2总线时钟
PLL时钟
PLL2时钟