锁相环是什么,为什么可以用来放大时钟频率,怎么做到的,还有预分频起,为什么可以进行分频和倍频?

一、锁相环(PLL)是什么?

锁相环(Phase-Locked Loop,PLL) 是一种反馈控制电路,它的核心功能是:

  • 使输出信号的相位与参考信号的相位保持同步

  • 从而间接使频率也同步,并且可以按设定比例放大频率

PLL 的基本组成(4个部分):

外部时钟(如8MHz晶振)

↓

  1. 鉴相器(Phase Detector, PD) ← 比较参考时钟和反馈时钟的相位差

↓

  1. 低通滤波器(Low-Pass Filter, LPF) ← 将相位差转换为电压信号(平滑)

↓

  1. 压控振荡器(Voltage-Controlled Oscillator, VCO) ← 电压控制输出频率

↓

  1. 分频器(/N) ← 将输出分频后反馈给鉴相器

└─────────────┘

这是一个闭环负反馈系统。


二、PLL 如何"放大"频率?

关键在分频器(/N)。

工作过程:

  1. 参考频率 = 外部晶振频率(如 8 MHz)

  2. 反馈回路 中有一个 ÷N 分频器

  3. 系统稳定时,鉴相器检测到的相位差为0,这意味着:

    参考频率=VCO输出频率N参考频率=NVCO输出频率

  4. 因此:

    VCO输出频率=参考频率×NVCO输出频率=参考频率×N

举例(STM32F103 常见配置):

外部晶振 = 8 MHz

PLL倍频系数 N = 9

则 PLL输出 = 8 MHz × 9 = 72 MHz

实际上PLL内部还有预分频器(M) 和后分频器(P、Q等),更完整的公式是:

fout=fin×N(M×P)fout​=fin​×(M×P)N​

在STM32F103中,常见的配置是输入8MHz,经过PLL后输出72MHz。


三、分频器为什么能分频?

数字分频原理(以预分频器为例):

分频器本质是一个计数器:

  • 每输入 N 个时钟脉冲,输出 1 个脉冲

  • 例如 ÷2 分频器:

输入时钟: ▁▁▁▁▁ (周期 T)

输出时钟: ▁▁▁▁▁▁_▁▁ (周期 2T)

频率减半,周期加倍。

实现方式:
  1. D触发器级联:每个D触发器实现÷2

    输入 → D1(Q) → D2(Q) → ... → 输出

    每个触发器在时钟上升沿翻转一次

  2. 计数器+比较器:可编程任意分频比

    计数器从0计数到N-1,然后复位并输出一个脉冲


四、为什么STM32F103C8T6要采用PLL作为系统时钟?

STM32F103C8T6的核心需求:

  • CPU需要高速运行(最高72 MHz)

  • 但外部晶振不能太高(通常4-16 MHz)

原因分析:

1. 高频晶振的缺点:
  • 成本高

  • 体积大

  • 功耗大

  • 稳定性差(高频下更易受干扰)

2. PLL的优点:
  • 使用低频晶振产生高频时钟(如8MHz晶振→72MHz系统时钟)

  • 频率灵活可调(通过配置倍频系数N)

  • 时钟质量好:PLL有滤波功能,输出时钟抖动小

  • 低功耗:外部晶振低频工作,内部PLL按需提供高频

3. STM32F103的时钟树结构:

外部晶振 (HSE, 8MHz)

↓

PLL倍频 (×9)

↓

系统时钟 (SYSCLK, 72MHz)

↓

分发给:CPU、AHB总线、APB总线等

4. 性能需求:
  • 72 MHz 时钟使CPU能快速执行指令

  • 高速外设(如SPI、定时器)需要高时钟频率

  • 但又要保持外部电路的简洁和低成本


五、PLL的实际配置(STM32F103代码示例)

cs 复制代码
// 典型配置:8MHz晶振 -> 72MHz系统时钟
void SystemClock_Config(void) {
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    
    // 1. 使能HSE(外部8MHz晶振)
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    
    // 2. 配置PLL:输入8MHz,输出72MHz
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;  // 倍频系数 N=9
    
    // 3. 设置AHB/APB分频
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;  // 系统时钟源选择PLL
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;        // AHB不分频 = 72MHz
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;         // APB1 = 36MHz(最大)
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;         // APB2 = 72MHz
}

六、总结对比表

特性 直接使用高频晶振 使用PLL(低频晶振+倍频)
外部晶振频率 高(如72MHz) 低(如8MHz)
成本 高 低
功耗 高 低(晶振部分)
频率灵活性 固定 可编程调节
时钟质量 一般 好(抖动小)
启动时间 短 稍长(PLL锁定时间)

核心要点记忆:

  1. PLL不是"放大"能量 ,而是通过反馈控制生成高频时钟信号

  2. 分频器本质是计数器,数到N就输出一个脉冲

  3. STM32用PLL 是为了:低成本晶振 + 高性能运行的完美平衡

  4. 锁相是关键:通过比较相位差来调整频率,直到相位锁定

这就是为什么现代MCU几乎都使用PLL技术来生成系统时钟------它实现了成本、性能和灵活性的最佳平衡。

相关推荐
一隅论数智4 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
不悔哥4 天前
开源OV-Watch:怎么做一个智能手表
单片机·开源·嵌入式
XiHongShi20164 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
爱吃苹果的日记本4 天前
离散数学第六课
学习·离散数学
优信电子4 天前
AIT1001 非接触式红外测温模块 STM32 驱动开发实战:从引脚到代码全解析
stm32·嵌入式·温度传感器·红外测温·非接触式测温·ait1001
AI职业加油站4 天前
AI智能体应用工程师证书:政策红利下的职业新风口
大数据·运维·人工智能·学习·职场发展
深圳老胡4 天前
STM32F407 控制 L6470 步进电机驱动 —— 控制过程简介
笔记·stm32·单片机·嵌入式硬件·代码规范
旖旎夜光4 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
奇思妙想聪明勤奋的小羊4 天前
DeepAgents第5章:子Agent 与上下文隔离—让 Agent学会委派
人工智能·python·学习·语言模型