STM32F103学习笔记-16-RCC(第4节)-使用 HSI 配置系统时钟并用 MCO 监控系统时钟

一、实验背景与目的

上一节课中,我们已经学习了如何使用外部高速时钟 HSE(High Speed External)作为系统时钟源,并通过 MCO(Microcontroller Clock Output)输出信号来验证时钟配置是否正确。

本节我们将继续深入学习:
如何使用内部高速时钟 HSI(High Speed Internal)配置系统时钟,并通过 MCO 输出验证系统频率。


二、HSI 的原理回顾

HSI 是 STM32 内部自带的高速 RC 振荡器(通常为 8 MHz),不依赖外部晶振。它启动速度快,但精度略低,一般用于:

  • 节省成本或无外部晶振时;

  • 在调试、测试阶段使用;

  • 或在低功耗快速启动应用中。

HSI 可直接作为系统时钟源,也可以经过 除 2 后作为 PLL 输入源,经倍频后生成更高频率。

例如:

HSI = 8 MHz

HSI / 2 = 4 MHz

若倍频因子 = 16 → 系统时钟 = 4 MHz × 16 = 64 MHz


三、代码分析与实现步骤

1. 头文件 bsp_rcclkconfig.h
复制代码
#ifndef __BSP_RCCLKCONFIG_H
#define __BSP_RCCLKCONFIG_H

#include "stm32f10x.h"

void HSE_SetSysClk(uint32_t RCC_PLLMul_x);
void MCO_GPIO_Config(void);
void HSI_SetSysClk(uint32_t RCC_PLLMul_x);

#endif

这里声明了三个函数:

  • HSE_SetSysClk():上节课的外部晶振配置函数。

  • MCO_GPIO_Config():配置 PA8 为时钟输出引脚。

  • HSI_SetSysClk():本节新增的函数,用于用 HSI 配置系统时钟。


2. 主函数 main.c
复制代码
int main(void)
{
  HSI_SetSysClk(RCC_PLLMul_16);  // 使用HSI × 16 = 64MHz
  MCO_GPIO_Config();              // 配置MCO输出引脚
  RCC_MCOConfig(RCC_MCO_SYSCLK);  // 输出系统时钟到PA8

  LED_GPIO_Config();              // 初始化LED
  while(1)
  {
    LED_G(OFF);
    Delay(0xFFFFF);
    LED_G(ON);
    Delay(0xFFFFF);
  }
}
程序逻辑讲解:
  1. HSI_SetSysClk()

    使用内部时钟 HSI 作为 PLL 输入,倍频后配置系统时钟为目标频率(例:64 MHz)。

  2. MCO_GPIO_Config()

    配置 PA8 为复用推挽输出,用于输出时钟信号。

  3. RCC_MCOConfig(RCC_MCO_SYSCLK)

    将系统时钟源(SYSCLK)输出到 MCO 引脚(PA8),以便用示波器测量。

  4. LED_GPIO_Config() 与循环闪灯

    通过 LED 闪烁的频率变化,粗略观察系统时钟的快慢。


3. bsp_rcclkconfig.c 的实现逻辑
复制代码
void HSI_SetSysClk(uint32_t RCC_PLLMul_x)
{
  __IO uint32_t HSIStatus;
  RCC_DeInit();                   // 复位RCC寄存器

  RCC_HSICmd(ENABLE);             // 使能HSI

  HSIStatus = RCC->CR & RCC_CR_HSIRDY;  // 判断HSI是否稳定

  if(HSIStatus == RCC_CR_HSIRDY)  // 若稳定则配置系统时钟
  {
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    FLASH_SetLatency(FLASH_Latency_2);

    RCC_HCLKConfig(RCC_SYSCLK_Div1);
    RCC_PCLK1Config(RCC_HCLK_Div2);
    RCC_PCLK2Config(RCC_HCLK_Div1);

    RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_x);  // HSI/2 × 倍频
    RCC_PLLCmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);   // 等待PLL稳定

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);             // 切换系统时钟源
    while(RCC_GetSYSCLKSource() != 0x08);                 // 等待切换完成
  }
  else
  {
    /* 如果HSI启动失败,可以在这里加入错误处理 */
  }
}
代码逻辑拆解:
步骤 动作 说明
RCC_DeInit() 将 RCC 寄存器恢复到复位状态,防止旧配置干扰。
RCC_HSICmd(ENABLE) 开启内部 8 MHz RC 振荡器。
RCC->CR & RCC_CR_HSIRDY 检查 HSI 是否准备就绪。
FLASH_SetLatency() 调整 Flash 等待周期,适应高频访问速度。
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_x) 设置 PLL 源为 HSI/2,并指定倍频因子。
RCC_PLLCmd(ENABLE) 启动 PLL 并等待其锁定(稳定)。
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK) 将系统时钟切换到 PLL 输出。
RCC_GetSYSCLKSource() 验证切换成功。

四、使用 MCO 输出验证时钟

1. 配置 GPIO(PA8)

复制代码
void MCO_GPIO_Config()
{
  GPIO_InitTypeDef GPIO_InitStruct;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStruct);
}

PA8 是 MCO 引脚(可输出 SYSCLK、HSI、HSE、PLLCLK/2 等信号)。

这里配置为复用推挽输出模式,以驱动示波器或外部电路。


2. 输出时钟信号

复制代码
RCC_MCOConfig(RCC_MCO_SYSCLK);

此函数将 系统时钟(SYSCLK) 输出到 PA8 引脚。

若想输出 HSI,可改为 RCC_MCOConfig(RCC_MCO_HSI)

若想输出 PLLCLK/2,可改为 RCC_MCOConfig(RCC_MCO_PLLCLK_Div2)


五、实验现象与验证

配置 理论频率 实际测量(示波器) 现象
HSE_SetSysClk(RCC_PLLMul_9) 72 MHz ≈ 72 MHz LED闪烁正常
HSI_SetSysClk(RCC_PLLMul_16) 64 MHz ≈ 64 MHz LED闪烁略慢
HSI_SetSysClk(RCC_PLLMul_12) 48 MHz ≈ 48 MHz LED闪烁更慢

若测得的频率与预期一致,则系统时钟配置成功。

示波器应接地良好,并断开蜂鸣器跳帽(PA8连接蜂鸣器会影响波形)。


六、实验总结

通过本节实验,我们学会了:

  1. 如何使用 HSI (内部时钟)通过 PLL 倍频配置系统时钟;

  2. 如何通过 MCO 输出验证系统时钟频率;

  3. 理解了固件库函数 RCC_HSICmdRCC_PLLConfigRCC_MCOConfig 的配合使用;

  4. 掌握了调试与验证时钟系统的基本方法。

相关推荐
Lester_11013 小时前
嵌入式学习笔记 - 关于看门狗定时器的喂狗的操作放在中断还是放在主循环
笔记·单片机·学习
bai5459363 小时前
LED闪烁功能代码详解
单片机·嵌入式硬件
缪懿3 小时前
JavaEE:多线程基础,多线程的创建和用法
java·开发语言·学习·java-ee
AA陈超4 小时前
ASC学习笔记0017:返回此能力系统组件的所有属性列表
c++·笔记·学习·ue5·虚幻引擎
谅望者4 小时前
数据分析笔记07:Python编程语言介绍
大数据·数据库·笔记·python·数据挖掘·数据分析
Cathy Bryant5 小时前
信息论(五):联合熵与条件熵
人工智能·笔记·机器学习·数学建模·概率论
小呀小萝卜儿5 小时前
2025-11-15 学习记录--Python-LSTM模型定义(PyTorch)
python·学习·lstm
XDHCOM5 小时前
通过手机远程操控电脑,一步步学习便捷方法
学习·智能手机·电脑
吃货界的硬件攻城狮6 小时前
【STM32】低功耗模式下的IO配置详解(标准库实现)
stm32·单片机·嵌入式硬件