目录
一、时钟框图
下图就是STM32F10x的时钟系统框图,此处用的正点原子的图,左侧四个蓝色的分别是:
高速内部RC时钟(HSI):8MHz,精度差,受电压温度影响。
高速外部晶振时钟(HSE):4-16MHz,一般用8MHz,常用HSE作为系统时钟。
低速外部晶振时钟(LSE):32.768kHz,一般给RTC做时钟源。
高速内部RC时钟(LSI):30-60kHz,一般给独立看门狗或者自动唤醒单元做时钟源。
根据框图,AHB使用系统时钟SYSCLK,SYSCLK有HSI、HSE以及PLLCLK三种选择,本次配置使用PLLCLK作为系统时钟,从HSE(8MHz)经过PLL倍频至72MHz。而后,AHB和ABP2一般给72MHz,AHB1为36MHz。
二、配置过程
1、系统时钟配置函数
配置顺序如下:
0、RCC初始化;
1、开启HSE ,并等待 HSE 稳定;
2、设置 AHB、APB2、APB1的预分频因子;
3、设置PLL的时钟来源,和PLL的倍频因子,设置各种频率主要就是在这里设置;
4、开启PLL,并等待PLL稳定;
5、把PLLCK切换为系统时钟SYSCLK;
6、读取时钟切换状态位,确保PLLCLK被选为系统时钟。
此处直接贴代码,整体就是RCC使能并等待状态位成功后,从上面系统框图的右边,也即外设部分,往左配置(AHB、APB1、APB2频率,PLL来源以及频率配置,系统时钟来源配置)。
void HSE_SYSCLK( uint32_t pllmul)
{
RCC_DeInit(); //先初始化RCC
ErrorStatus HSEStatus; //枚举变量:0为ERROR,1为SUCCESS
RCC_HSEConfig(RCC_HSE_ON); //使能HSE
HSEStatus = RCC_WaitForHSEStartUp(); //等待RCC稳定,稳定后返回SUCCESS
if (HSEStatus == SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); // 使能FLASH 预存取缓冲区
FLASH_SetLatency(FLASH_Latency_2); //延迟设置,CPU等待FLASH两个周期,根据SYSCLK频率设置
//此处开始可以看成从后往前配置,即从外设时钟到锁相环
RCC_HCLKConfig(RCC_SYSCLK_Div1); // AHB预分频因子设置为1分频,HCLK = SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1); // APB2预分频因子设置为1分频,PCLK2 = HCLK
RCC_PCLK1Config(RCC_HCLK_Div2);// APB1预分频因子设置为1分频,PCLK1 = HCLK/2
// 设置PLL时钟来源为HSE,设置PLL倍频因子
// PLLCLK = 8MHz * pllmul
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, pllmul);
RCC_PLLCmd(ENABLE); // 开启PLL
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) // 等待 PLL稳定
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // 当PLL稳定之后,把PLL时钟切换为系统时钟SYSCLK
// 读取时钟切换状态位,确保PLLCLK被选为系统时钟
while (RCC_GetSYSCLKSource() != 0x08)
{
}
}
else
{ // 如果HSE开启失败,那么程序就会来到这里,用户可在这里添加出错的代码处理
// 当HSE开启失败或者故障的时候,单片机会自动把HSI设置为系统时钟,HSI是内部的高速时钟,8MHZ
while (1)
{
}
}
}
2、MCO配置
首先,MCO是和PA8的端口复用,作为输出,应该配置模式为复用推挽输出,同时,在系统时钟作为输出至MCO引脚时,保证输出时钟频率不超过50MHz (I/O口最高频率)。其余操作与正常外设相同,先声明GPIO结构体,使能APB2时钟,引脚、模式、速率三个成员配置,最后初始化这个结构体,之后就可以在PA8口用示波器看系统时钟频率(MCO可以查看SYSCLK、HSI、HSE、PLL/2四个频率,在RCC_CFGR中配置)
void MCO_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 开启GPIOA的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 选择GPIO8引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
//设置为复用功能推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//设置IO的翻转速率为50M
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// 初始化GPIOA8
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
参考
[野火®]STM32库开发实战指南——基于野火指南者开发板 — [野火]STM32库开发实战指南——基于野火指南者开发板 文档