概述
实际使用STM32F103单片机时,第一步就是配置系统的工作时钟。我们时常需要选择使用外部时钟源和内部时钟源,这里我们以F103为例子,提供两个函数参考,供大家实际开发中使用配置系统时钟。
实例
废话不多说,直接上代码。
#include "dri_sysclk.h"
static void SetSystemClk(eSelectClkSrc _ClkSrc);
T_SysClk_Device g_tSysClk_Dev = {
.SysClkConfig = SetSystemClk
};
static void SetSysClockTo64(void)
{
__IO ErrorStatus HSIStartUpStatus = 0;
/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------------------------*/
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSI */
RCC_HSICmd(ENABLE);
/* Wait till HSI is ready */
if((RCC->CR & RCC_CR_HSIRDY) == RCC_CR_HSIRDY)
HSIStartUpStatus = SUCCESS;
else
HSIStartUpStatus = ERROR;
if(HSIStartUpStatus == SUCCESS)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* PLLCLK = 8MHz / 2 * 16 = 64 MHz */
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
else
{ /* If HSI fails to start-up, the application will have wrong clock configuration.
User can add here some code to deal with this error */
/* Go to infinite loop */
while (1)
{
}
}
}
static void SetSysClockTo72(void)
{
__IO ErrorStatus HSEStartUpStatus = ERROR;
/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------------------------*/
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
else
{ /* If HSE fails to start-up, the application will have wrong clock configuration.
User can add here some code to deal with this error */
/* Go to infinite loop */
while (1)
{
}
}
}
static void SetSystemClk(eSelectClkSrc _ClkSrc)
{
switch(_ClkSrc)
{
case USE_HSE_FOR_CLKSRC:
SetSysClockTo72();
break;
case USE_HSI_FOR_CLKSRC:
SetSysClockTo64();
break;
default:
break;
}
/* Enable Clock Security System(CSS): this will generate an NMI exception
when HSE or HSI clock fails */
RCC_ClockSecuritySystemCmd(ENABLE);
}
结论
通过上述配置,我们就可以成功配置系统时钟。