上电调用的时钟函数
static void SetSysClockTo72(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
/* 使能 HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/*等待SHE就绪并做超时处理*/
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
//
if (HSEStatus == (uint32_t)0x01)
{
/* Enable Prefetch Buffer 使能预取值,PC可以存下一条指令, 下面3条是flash内置内存的控制器*/
FLASH->ACR |= FLASH_ACR_PRFTBE;
/* Flash 2 wait state */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
/*配置AHB APB2 APB1的分频因子*/
/* HCLK = SYSCLK = 72M*/
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK = 72M*/
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK = 36M*/
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
/* 配置锁相环PLL*/
/* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
/* 使能 PLL */
RCC->CR |= RCC_CR_PLLON;
/* 等待锁相环PLL稳定,读取为1代表稳定 */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* 选择 PLL 作为系统时钟 */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
/* 等待PLL切换成系统时钟稳定 */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)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 如果SHE启动失败,用户可以在这里添加处理代码*/
}
}
2:重新配置时钟的频率
//配置HSE为系统时钟
void HSE_SetSysClk(uint32_t RCC_PLLMul_x)
{
ErrorStatus HSEstatus;
//把RCC复位到起始状态
RCC_DeInit();
//使能HSE
RCC_HSEConfig(RCC_HSE_ON);
HSEstatus = RCC_WaitForHSEStartUp();
if (HSEstatus == SUCCESS)
{
//启动成功
}
else
{
//启动失败, 添加其他代码
}
//使能预取值
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//设置2个等待演示
FLASH_SetLatency(FLASH_Latency_2);
//配置HPLC APB1 APB2
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
//配置锁相环
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_x);//配置PLLCLK = HSE * RCC_PLLMul_x
//使能PLL
RCC_PLLCmd(ENABLE);
//等待PLL稳定
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
//选择系统时钟来源
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//等待成功
while (RCC_GetSYSCLKSource() != 0x08);
}
//配置HSI为系统时钟
void HSI_SetSysClk(uint32_t RCC_PLLMul_x)
{
__IO uint32_t HSIStatus = 0;
//把RCC复位到起始状态
RCC_DeInit();
//使能HSI
RCC_HSICmd(ENABLE);
HSIStatus = RCC->CR & RCC_CR_HSIRDY;
if (HSIStatus == RCC_CR_HSIRDY)
{
//启动成功
}
else
{
//启动失败, 添加其他代码
}
//使能预取值
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//设置2个等待演示
FLASH_SetLatency(FLASH_Latency_2);
//配置HPLC APB1 APB2
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
//配置锁相环
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_x);//配置PLLCLK = HSI / 2 * RCC_PLLMul_x
//使能PLL
RCC_PLLCmd(ENABLE);
//等待PLL稳定
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
//选择系统时钟来源
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//等待成功
while (RCC_GetSYSCLKSource() != 0x08);
}
//把MCO的时钟输出的引脚进行配置,可以通过示波器量测这个引脚观测时钟频率
//可以通过这个 函数配置这个函数确定引脚输出哪个时钟
//RCC_MCOConfig(RCC_MCO_SYSCLK);//输出SYSCLK,
//RCC_MCOConfig(RCC_MCO_HSE);//输出HSE时钟
void MCO_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitSturct;
GPIO_InitSturct.GPIO_Pin = GPIO_Pin_8;
GPIO_InitSturct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitSturct.GPIO_Speed = GPIO_Speed_50MHz;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_Init(GPIOA, &GPIO_InitSturct);
}