[APM32F1] APM32微控制器系统时钟架构详解

[复制链接]
 楼主| lc115647 发表于 2025-3-22 21:17 | 显示全部楼层 |阅读模式
[md]# APM32微控制器系统时钟架构详解

# 一、概述

APM32系列微控制器(MCU)作为高性能嵌入式系统的核心,其时钟系统是确保系统稳定性和能效的关键。本文将深入剖析APM32的时钟架构,涵盖时钟源、配置方法及典型应用场景,助力开发者优化系统设计。

---

## 二、APM32时钟源解析

APM32提供多级时钟源,满足不同场景需求:

### 1. 高速时钟源

- **HSE(外部高速振荡器)**
  - 4~32MHz外部晶体/陶瓷谐振器,提供高精度时钟。
  - 典型应用:USB通信、高精度定时器、以太网PHY同步。
- **HSI(内部高速RC振荡器)**
  - 8/16MHz(型号相关)内置RC,快速启动但精度较低(±1%~±2%)。
  - 用途:系统时钟备份、看门狗时钟源。

### 2. 低速时钟源

- **LSE(外部低速振荡器)**
  - 32.768kHz晶体,低功耗且高精度,用于RTC和低功耗模式。
- **LSI(内部低速RC振荡器)**
  - ~40kHz RC振荡器,独立时钟源,用于看门狗、自动唤醒。

### 3. PLL(锁相环倍频器)

- 将HSE/HSI时钟倍频至最高216MHz(具体型号需查数据手册)。
- 支持多级分频/倍频系数,灵活适配外设需求。
  以APM32F103系统时钟为例,如下图所示:

## 三、时钟树与信号分配

APM32时钟树采用分层结构,关键路径如下:

1. **系统时钟(SYSCLK)**:由HSI/HSE/PLL提供,经AHB分频后驱动内核、内存及高速外设。
2. **APB总线时钟**:由AHB分频得到,控制低速外设(如UART、SPI)。
3. **独立时钟域**:RTC、看门狗、独立定时器等拥有专用时钟源,确保关键功能稳定性。

**时钟切换机制**:支持无中断切换(如HSE故障时自动切至HSI),需配置CSS(时钟安全系统)。

---

## 四、时钟配置实战指南

### 1. 配置HSE为系统主时钟源

1. 使能HSE:等待振荡器稳定(检查 `RCM_WaitHSEReady`)。
2. 配置PLL参数:选择输入源(HSE)、设置倍频因子(PLLM/PLLN)。
3. 切换系统时钟源至PLL:通过 `RCM_ConfigSYSCLK()`实现。
4. 验证配置:检查时钟状态寄存器或使用 `RCM_ReadSYSCLKSource()`函数。

**基于APM32标准库**:

```c
void ConfigClockSourceHSE(void){
  
    RCM_Reset();                                                //重置系统时钟
  
    RCM_ConfigHSE(RCM_HSE_OPEN);                                   //使能内部时钟HSE
  
    if((RCM_WaitHSEReady() == SUCCESS))                         //等待HSE使能就绪
    {  
        RCM_ConfigPLL(RCM_PLLSEL_HSE, RCM_PLLMF_12);            //配置HSE为PPL时钟源,倍频系数为16  8*12= 96M
        RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_PLL);                    //配置PLL为sysclk来源
  
        RCM_ConfigAHB(RCM_AHB_DIV_1);                            //配置AHP分频系数为1    96M
        RCM_ConfigAPB1(RCM_APB_DIV_2);                            //配置APB1分频系数为2    48M
        RCM_ConfigAPB2(RCM_APB_DIV_1);                            //配置APB2分频系数为1    96M
  
        RCM_EnablePLL();                                        //使能PLL
        while((RCM_ReadStatusFlag(RCM_FLAG_PLLRDY) == RESET));    //等待PLL就绪
        while(RCM_ReadSYSCLKSource()!=RCM_SYSCLK_SEL_PLL);        //读取SYSCLK来源是否为PLL
    }
}   
```

### 2. 配置HSI为系统主时钟源

```
1.使能HSE:等待振荡器稳定(检查
```

`RCM_WaitHSEReady`)。

```
2.配置PLL参数:选择输入源(HSE)、设置倍频因子(PLLM/PLLN)。
```


```
3.切换系统时钟源至PLL:通过
```

`RCM_ConfigSYSCLK()`实现。

```
4.验证配置:检查时钟状态寄存器或使用
```

`RCM_ReadSYSCLKSource()`函数。

```
void ConfigClockSourceHSI(void){
  
        RCM_Reset();                                                //重置系统时钟
      
        RCM_ConfigHSITrim(0x00);                                    //HSI校正
        RCM_EnableHSI();                                               //使能内部时钟HSI
         
        while((RCM_ReadStatusFlag(RCM_FLAG_HSIRDY) == RESET));      //等待HSI使能就绪
   
        FMC_EnablePrefetchBuffer();                                  /* 使能Flash预取缓冲区 */
        FMC_SetLatency(FMC_LATENCY_4);                                  /* 设置Flash访问等待周期个数为4个 */  
      
        RCM_ConfigPLL(RCM_PLLSEL_HSI_DIV_2, RCM_PLLMF_16);            //配置HSI/2为PPL时钟源,倍频系数为16  4*16= 64M
        RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_PLL);                        //配置PLL为sysclk来源
      
        RCM_ConfigAHB(RCM_AHB_DIV_1);                                //配置AHP分频系数为1
        RCM_ConfigAPB1(RCM_APB_DIV_2);                                //配置APB1分频系数为2
        RCM_ConfigAPB2(RCM_APB_DIV_1);                                //配置APB2分频系数为1
      
        RCM_EnablePLL();                                            //使能PLL
        while((RCM_ReadStatusFlag(RCM_FLAG_PLLRDY) == RESET));        //等待PLL就绪
        while(RCM_ReadSYSCLKSource()!=RCM_SYSCLK_SEL_PLL);            //读取SYSCLK来源是否为PLL
}
```

### 3. 低功耗模式下的时钟优化

- **睡眠模式**:关闭APB外设时钟,保持CPU时钟运行。
- **停止模式**:关闭HSI/HSE,仅保留LSI/LSE。
- **待机模式**:仅保留RTC和看门狗时钟。

---

### 4.系统时钟输出

如上图系统时钟树所示,MCO能将HSI、HSE、PLL/2、SYS四种时钟输出到芯片IO口上,常用于在芯片异常分析中,验证当前MCU时钟是否存在异常现象,可通过MCOSEL寄存器选择输出时钟的类型,但最好保证系统时钟输出不超过50Mhz。
![image.png](data/attachment/forum/202503/22/211356cb18n68d83rz8oad.png "image.png")

具体配置代码如下:

```
void Confige_Clock_Out(void){
    GPIO_Config_T  configStruct;
    /* Enable the GPIOA Clock */
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
  
    /* Configure the GPIO_A pin */
    configStruct.pin = GPIO_PIN_8;
    configStruct.mode = GPIO_MODE_AF_PP;
    configStruct.speed = GPIO_SPEED_50MHz;
  
    GPIO_Config(GPIOA, &configStruct);
  
    RCM_ConfigMCO(RCM_MCOCLK_SYSCLK);
}

```

## 五、常见问题与调试技巧

### 1. 时钟启动失败

- **症状**:程序卡在 `while(HSE未就绪)`。
- **排查步骤**:
  - 检查硬件:晶体焊接、负载电容(通常10~22pF,参考数据手册)。
  - 降低HSE频率测试,排除PCB布线干扰。
  - 启用CSS(时钟安全系统)并触发NMI中断处理故障。

### 2. 外设无响应

- **原因**:未使能外设时钟(APB/APB1ENR寄存器)。
- **解决**:调用 `RCC_APBxPeriphClockCmd()`使能对应外设时钟。

### 3. 电磁干扰(EMI)

- **对策**:
  - 缩短晶振走线,远离高频信号线。
  - 在时钟信号线串联33Ω电阻抑制反射。

---

## 六、总结

APM32的灵活时钟架构为系统设计提供了高可靠性和能效平衡。开发者需根据实际需求选择时钟源,合理配置分频系数,并结合低功耗模式优化整体方案。建议结合官方时钟配置工具(如APM32 Clock Configurator)加速开发流程。
[/md]
image.png
image.png
image.png
霜之闪耀 发表于 2025-3-26 00:05 | 显示全部楼层
这总结的也太详细了吧!
我一直在考虑时钟的CSS晶振保护的功能如何出现?感觉也没有啥意义
夜幕叙事曲 发表于 2025-5-30 22:58 | 显示全部楼层
极海官方有时钟配置工具呀!
一直没有注意,赶紧去看看
涡流远见者 发表于 2025-5-31 08:44 | 显示全部楼层
现在晶振这么便宜,选择外置的HSE成本上应该也能接受吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

28

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部