前言
使用stm32cubMX生成项目时候,在软件中配置TIM2定时器为PWM输出引脚,一共四路可以驱动四个电机,但是我的舵机一直没有转动,没有看到代码有什么问题,后面核查发现,没有使能锁相环PLL,但是工程出来的始终频率一直是72M,不使能PLL的话应该是使用默认的8M的时钟频率,定时器2的分频器设置应该是8000-1(8M晶振的分频系数),这里不知道是STM32CUBMX本身问题还是我设置问题,后面通过软件使能时钟后,要软件仿真查看下系统实际时钟频率是多少。所以后面写了这篇文档详细理解下STM32的时钟相关。
下面图1是不使用PLL倍频,使用8M系统时钟的舵机配置的分频系数,分频到1khz,20ms
下面图2是使用PLL倍频到72M系统时钟的舵机配置,分频到1khz,20ms
STM32F103 时钟系统分类与使用
下图找了一个网络上的stm32核心板子,描述两个外部晶振的位置。
1. 时钟系统概述
STM32F103 采用多级时钟树结构,支持多种时钟源以适应不同的功耗和性能需求。正确理解和使用时钟系统对于确保系统稳定运行至关重要。下图是典型的时钟树的图,我们做下区分学习,先关注四大始终源头。
2. 时钟来源分类
STM32F103 的时钟来源主要包括以下几类:
2.1 外部时钟(HSE - High Speed External)
HSE 晶振模式(晶体振荡器):通常使用 4MHz - 16MHz 的外部晶振作为主时钟源。一般外部都是使用晶振,外部时钟模式比较少,基本可以忽略。
HSE 外部时钟模式(外部时钟输入):可直接输入一个时钟信号。
HSE 主要用于高精度应用,如 USB、CAN、以太网等。
2.2 内部时钟
HSI(High Speed Internal):8MHz RC 振荡器,精度较低,适用于低功耗应用。
LSI(Low Speed Internal):约 40kHz 低速 RC 振荡器,常用于独立看门狗(IWDG)和低功耗模式。
2.3 低速外部时钟(LSE - Low Speed External)
通常为 32.768kHz 石英晶振,主要用于 RTC(实时时钟)保持计时。
3. 时钟树结构
STM32F103 的时钟系统由多个时钟源组成,经过分频、倍频和切换后,提供给不同的外设。
3.1 主要时钟路径
系统时钟(SYSCLK):主时钟,可选择 HSI、HSE 或 PLL 输出。
AHB 时钟(HCLK):用于 Cortex-M3 内核、存储器、DMA、APB 总线。
APB1 时钟(PCLK1):低速外设时钟,如 TIM2-7、USART2-5。
APB2 时钟(PCLK2):高速外设时钟,如 GPIO、ADC、USART1、SPI1、TIM1、TIM8。
3.2 PLL(Phase Locked Loop - 锁相环)
锁相环(PLL)是一个用于生成高频时钟的电路,可通过倍频提高系统时钟频率。
3.2.1 PLL 输入源
PLL 的输入可以是:
HSI/2(即 HSI 8MHz 经过 2 分频,得到 4MHz 作为 PLL 输入)
HSE(可直接使用 HSE,或者经过 2 分频后输入 PLL)
3.2.2 PLL 乘法因子
PLL 可以将输入时钟进行倍频,STM32F103 的 PLL 乘法因子范围为 x2 到 x16,但输出频率不得超过 72MHz。例如:
使用 8MHz HSE,并配置 PLL 乘数为 9,可生成 72MHz 时钟。
使用 4MHz HSE 并配置 PLL 乘数为 12,同样可生成 48MHz 时钟。
3.2.3 PLL 输出
PLL 输出可作为 系统时钟(SYSCLK),用于驱动整个芯片。
PLL 也可用于 USB 时钟(48MHz),需确保 PLL 输出满足 USB 48MHz 需求。
3.2.4 PLL 配置注意事项
PLL 不能在运行时动态修改,必须先禁用 PLL,然后重新配置并重新启用。
PLL 输出受限于 72MHz,超过该频率可能导致系统不稳定。
使用 HSE 时需确保晶振稳定,否则可能导致启动失败。
4. 时钟配置
4.1 使用标准外设库(StdPeriph)
#include "stm32f10x.h"
void SystemClock_Config(void) {
RCC_DeInit(); // 复位 RCC 寄存器
RCC_HSEConfig(RCC_HSE_ON); // 使能 HSE
if (RCC_WaitForHSEStartUp() == SUCCESS) {
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // 配置 PLL
RCC_PLLCmd(ENABLE); // 使能 PLL
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); // 等待 PLL 就绪
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // 选择 PLL 作为系统时钟
while (RCC_GetSYSCLKSource() != 0x08); // 确保 PLL 被选为系统时钟
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
4.2 使用 HAL 库
void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
5. 常见问题及优化建议
5.1 时钟无法启动
检查 HSE 外部高速晶振是否正确接入,不开启PLL一般默认晶振频率是外部时钟频率HSE
确保 PLL 配置符合 STM32F103 的倍频规则。
5.2 低功耗模式下的时钟切换
低功耗模式可使用 HSI 或 LSI 以降低功耗。
进入 STOP 模式前,可切换系统时钟到 HSI,提高唤醒速度。
5.3 提高时钟稳定性
在 PCB 设计中,确保 HSE 晶振附近的负载电容匹配。
使用 LSE 时,建议选用低功耗 32.768kHz 晶振,并确保负载电容正确。
5.4 电机PWM输出异常
舵机或者其他PWM控制的电机无法驱动,可能是系统时钟设置的有问题,如8M的外部晶振作为时钟源,不使用PLL倍频的话,分频系数应该就是7999,分到1khz 20ms的数值。
6.总结
STM可选时钟源有4个,分别是HSE、LSE、LSI和HSI,前两个是外部晶体震荡产生的时钟源,后两个是内部RC电路震荡产生的时钟源。
通过开启PLL锁相环可以倍频出最大72MHz(使用8M HSE)的系统时钟频率。
PLL的作用是倍频,从四个时钟源里面选择一个进行倍频,倍频前时钟源可以自行进行分频,从而达到预期的始终频率。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_39642740/article/details/146376483
|