#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時鐘