内部时钟HSI的配置方式和HSE基本一致,唯一的一个区别在于,没有等待HSI就绪的函数,因此需要操作RCC_CR寄存器的HSIRDY位来判断时钟就绪,其他直接按流程即可。
bsp_rccclkconfig.c
/* RCC时钟配置函数 */
#include "bsp_rccclkconfig.h"
// 自定义时钟配置函数
void HSI_SetSysClk(uint32_t RCC_PLLMul_x)
{
// 因为操作的是寄存器,所以加上__IO,每次去地址读
__IO uint32_t HSIStatus;
// 把RCC时钟复位成复位值
RCC_DeInit();
// 使能HSI
RCC_HSICmd(ENABLE);
// 等待获取HSE启动状态
HSIStatus = RCC->CR & RCC_CR_HSIRDY;
// HSE启动成功
if (HSIStatus == RCC_CR_HSIRDY)
{
// 使能预取指,这个函数直接去stm32f10x_flash.h中找到
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
// 设置延时,latency表示“延迟”,同样在stm32f10x_flash.h中找到
FLASH_SetLatency(FLASH_Latency_2);
// 配置三条总线的分频因子
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
// 配置PLL锁相环的输入源为HSI二分频(4M)
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_x);
RCC_PLLCmd(ENABLE);
// 等待PLL准备就绪
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
;
// 选择PLLCLK作为系统时钟
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
// 等待系统时钟切换成功并稳定
while (RCC_GetSYSCLKSource() != 0x08)
;
}
// HSE启动失败
else
{
// 如果HSI启动失败,添加错误处理代码
}
}
// MCO引脚配置函数,用于检测时钟,包括HSE PLLCLK LSE HSI等
void MCO_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
bsp_rccclkconfig.h
#ifndef __BSP_RCCCLKCONFIG_H
#define __BSP_RCCCLKCONFIG_H
#include "stm32f10x.h"
void HSI_SetSysClk(uint32_t RCC_PLLMul_x);
void MCO_GPIO_Config(void);
#endif /* __BSP_RCCCLKCONFIG_H */
最后在主函数中调用和测试
main.c
#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_rccclkconfig.h"
void delay(uint32_t count);
int main(void)
{
// 来到这里时,系统时钟已经被配置成72MHz
// 必须要先复位时钟,因为系统上电就会执行systeminit函数配置时钟
// 此函数已经放在HSE_SetSysClk函数内
// RCC_DeInit();
// 内部时钟HSI倍频,最大64MHz
HSI_SetSysClk(RCC_PLLMul_16);
// 初始化MCO的GPIO
MCO_GPIO_Config();
// 选择系统时钟输出(检测sysclk)
RCC_MCOConfig(RCC_MCO_SYSCLK);
LED_GPIO_Config();
while (1)
{
LED_YELLOW;
delay(0XFFFFF);
LED_ALL_OFF;
delay(0XFFFFF);
}
}
void delay(uint32_t count)
{
for (; count != 0; count--);
}