时钟树:
HSE OSC(8M)——PLLSRC——PLLMUL(倍频*9=72M)——PLLCLK——SYSCLK(72M)—— AHB预分频(*1)——APB1(*1/2=36M)——PCLK1
可根据不同外设情况配置不同的时钟
//相关图片来自STM32F10x-中文参考手册
系统时钟默认为72MHz
static void SetSysClockTo72(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
//SYSCLK, HCLK, PCLK2 and PCLK1 configuration
//使能HSE 位16
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
//等待HSE就绪,并作超时处理 位17
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;
}
//如果HSE启动成功,则程序继续往下执行
if (HSEStatus == (uint32_t)0x01)
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;
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
// HCLK = SYSCLK =72M
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
//PCLK2 = HCLK =72M
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
// PCLK1 = HCLK =36M
RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
//锁相环配置 PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz 16-21位
RCC->CR |= RCC_CR_PLLON;
//使能PPL 24位
while((RCC->CR & RCC_CR_PLLRDY) == 0)
//判断是否置1 25位
{
}
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
//选择PPL作为系统时钟
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
//等待PPL切换为系统时钟
{
}
}
else //如果HSE启动失败,在此添加代码
{
}
}
#endif
使用HSE配置系统时钟
可以通过控制HSE_SetSysCLK(uint32_t RCC_PLLMul_x)中x的值来控制灯的亮灭快慢
rccclkconfig.c
#include "rccclkconfig.h"
#include "stm32f10x.h"
void HSE_SetSysCLK(uint32_t RCC_PLLMul_x)
{
ErrorStatus HSEStatus; //typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;定义需放在函数最前面
RCC_DeInit(); //复位
RCC_HSEConfig(RCC_HSE_ON); //使能HSE
HSEStatus=RCC_WaitForHSEStartUp(); // 等待HSE就绪
if(HSEStatus==SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //使能欲取指
FLASH_SetLatency(FLASH_Latency_2); // 72M配置成2个等待
RCC_HCLKConfig(RCC_SYSCLK_Div1); //HCLK一分频
RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK1二分频
RCC_PCLK2Config(RCC_HCLK_Div1); //PCLK2一分频
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_x); //锁相环配置
RCC_PLLCmd(ENABLE); //使能
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET); //等待PLL稳定
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //选择系统时钟
while(RCC_GetSYSCLKSource()!=0x08);
}
else
{
}
}
rccclkconfig.h
#ifndef _RCCCLKCONFIG_H
#define _RCCCLKCONFIG_H
#include "stm32f10x.h"
void HSE_SetSysCLK(uint32_t RCC_PLLMul_x);
#endif
主函数
#include "bsp-led2.h"
#include "stm32f10x.h"
#include "delay.h"
#include "rccclkconfig.h"
int main(void)
{
LED_GPIO_Config(); //LED端口初始化
delay_init(); //初始化延迟函数
HSE_SetSysCLK(RCC_PLLMul_9); //初始化RCC函数
while(1)
{
PBout(5)=0;
delay_ms(500);
PBout(5)=1;
delay_ms(500);
}
}