//学习RCC的配置方法,以后可以直接用
#include "stm32f10x_lib.h"
//#define SYSCLK_HSE
//#define SYSCLK_FREQ_20MHz
//#define SYSCLK_FREQ_36MHz //36MH工作
//#define SYSCLK_FREQ_48MHz //48MH工作 通过宏定义改变系统时钟频率
#define SYSCLK_FREQ_72MHz //工作72MH
#define DELAY_COUNT 0xFFFFF
GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO配置的结构体变量,用于初始化设置GPIO
RCC_ClocksTypeDef RCC_ClockFreq; //定义RCC时钟频率配置的结构体变量,用于配置RCC。包括SYSCLK,HCLK,PCLK1,PCLK2,ADCCLK频率的设置
ErrorStatus HSEStartUpStatus; //定义枚举类型的错误变量
//设置系统时钟SYSCLK的函数
void SetSysClock(void);
void SetSysClockToHSE(void);
void SetSysClockTo20(void);
void SetSysClockTo36(void);
void SetSysClockTo48(void);
void SetSysClockTo72(void);
void NVIC_Configuration(void); //配置嵌套向量中断控制器函数
void Delay(vu32 nCount); //延迟
int main(void)
{
#ifdef DEBUG
debug();
#endif
SetSysClock(); //设置系统时钟 HCLK PCLK2 PCLK1
RCC_GetClocksFreq(&RCC_ClockFreq); //获得不同片上时钟的频率,RCC_ClockFreq为前面定义的时钟频率结构体变量,该函数把当前
//不同片上时钟的频率存放在结构体RCC_ClockFreq中
RCC_ClockSecuritySystemCmd(ENABLE); //该函数使能或失能时钟安全系统 在这里是使能
NVIC_Configuration();
//开启GPIOA 和 GPIOB 模块时钟 使能APB2时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; //选择6,7,8,9引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO速度为50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出模式
GPIO_Init(GPIOB, &GPIO_InitStructure); //用刚刚配置好的结构体变量初始化PB口
GPIO_Write(GPIOB, GPIO_Pin_7 | GPIO_Pin_9); //向GPIOB口写入数据
//MCO:微控制器时钟输出 时钟能够输出到外部的MCO管脚,相关的GPIO管脚必须被配置成备用功能模式 即AF模式
//在STM32F103C8中PA8为MCO管脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //选择第8脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出模式
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA口
//在STM32F103C8中PA8为MCO管脚
RCC_MCOConfig(RCC_MCO_HSE); //选择在MCO管脚上输出的时钟源 参数设置指定输出的时钟源,可取值如下:
//RCC_MCO_NoClock:无时钟被选中,RCC_MCO_SYSCLK:选中系统时钟,RCC_MCO_HSI:选中HSI,RCC_MCO_HSE:选中HSE,RCC_MCO_PLLCLK_Div2:
//选中PLL时钟除以2
//警告:当选中系统时钟作为MCO管脚的输出时,注意它的时钟频率不超过50MHz(最大I/O速率)。
while (1)
{
GPIO_Write(GPIOB, (u16)~GPIO_ReadOutputData(GPIOB)); //PB口的状态取反
Delay(DELAY_COUNT);
}
}
void SetSysClock(void) //设定系统时钟频率函数
{
#if defined SYSCLK_HSE
SetSysClockToHSE(); //系统时钟频率设为HSE
#elif defined SYSCLK_FREQ_20MHz
SetSysClockTo20(); //系统时钟频率设为20MHz
#elif defined SYSCLK_FREQ_36MHz
SetSysClockTo36(); //系统时钟频率设为36MHz
#elif defined SYSCLK_FREQ_48MHz
SetSysClockTo48(); //系统时钟频率设为48MHz
#elif defined SYSCLK_FREQ_72MHz
SetSysClockTo72(); //系统时钟频率设为72MHz
#endif
}
void SetSysClockToHSE(void) //设置系统时钟频率为HSE的函数
{
//复位RCC外部设备寄存器到默认值
RCC_DeInit(); //将外设RCC寄存器重设为缺省值
RCC_HSEConfig(RCC_HSE_ON);//打开外部高速晶振HSE
HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速时钟准备好
if (HSEStartUpStatus == SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //使能flash的预取功能
FLASH_SetLatency(FLASH_Latency_0); //设置flash代码延时时钟周期数为0
RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置AHB时钟等于系统时钟
RCC_PCLK2Config(RCC_HCLK_Div1); //设置APB2时钟频率等于AHB时钟
RCC_PCLK1Config(RCC_HCLK_Div1); //设置APB1时钟频率等于AHB时钟
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);//设置系统时钟为HSE
while (RCC_GetSYSCLKSource() != 0x04) //检查系统时钟是否为HSE 0x04:HSE作为系统时钟
{
}
}
else
{
while (1)
{
}
}
}
void SetSysClockTo20(void) //设置系统时钟频率为20MHz
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_0);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div1);
RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_5); // HSE为8MHz 设置PLL输出频率为20MHz
RCC_PLLCmd(ENABLE); //使能PLL
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)//等待PLL就绪
{
}
[page]
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //配置系统时钟为PLL
while (RCC_GetSYSCLKSource() != 0x08) //检查系统时钟是否为PLL
{
}
}
else
{
while (1)
{
}
}
}
void SetSysClockTo36(void) //设置系统时钟为36MHz函数
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_1);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div1);
RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_9); //8/2 *9=36 设置PLL为36MHz
RCC_PLLCmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while (RCC_GetSYSCLKSource() != 0x08)
{
}
}
else
{
while (1)
{
}
}
}
void SetSysClockTo48(void) //设置系统时钟为48MHz函数
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_1);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_6); //设置PLL为48MHz
RCC_PLLCmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while (RCC_GetSYSCLKSource() != 0x08)
{
}
}
else
{
while (1)
{
}
}
}
void SetSysClockTo72(void) //设置系统时钟为72MHz
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //设置PLL为72MHz
RCC_PLLCmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
else
{
while (1)
{
}
}
}
void NVIC_Configuration(void) //设置中断向量表基址
{
NVIC_InitTypeDef NVIC_InitStructure; //NVIC初始化结构体,定义初始化NVIC的结构体变量
#ifdef VECT_TAB_RAM
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
//NVIC_InitStructure 是前面定义的NVIC初始化结构体 包括以下几项
NVIC_InitStructure.NVIC_IRQChannel = RCC_IRQChannel; //指定IRQ通道 这里指定为RCC全局中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //该参数设置成员NVIC_IRQChannel中的先占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //该参数设置成员NVIC_IRQChannel中的从优先级 详见函数说明P167
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //该参数指定在成员NVIC_IRQChannel中定义的IRQ通道被使能还是失能
//取值可以为ENABLE或DISABLE
NVIC_Init(&NVIC_InitStructure); //根据结构体NVIC_InitStructure中指定的参数初始化外设NVIC
}
void Delay(vu32 nCount)
{
for(; nCount!= 0;nCount--);
}
#ifdef DEBUG
//assert_failed编写于文件main.c或其他用户C文件中
void assert_failed(u8* file, u32 line)
{
while (1)
{
}
}
#endif
关键字:STM32 RCC系统 时钟配置