您现在的位置是:首页 >技术教程 >【STM32】基础知识 第十一课 时钟网站首页技术教程

【STM32】基础知识 第十一课 时钟

我是小白呀 2023-07-16 00:00:02
简介【STM32】基础知识 第十一课 时钟

概述

STM32 微控制器具有复杂的时钟系统, 用于为处理器内核, 外设和总线提供时钟信号. 了解 STM32 的时钟系统对于掌握其工作原理和进行高效开发至关重要.

STM32 时钟

时钟系统的基本概念

什么是时钟

时钟 (Clock) 提供了一个周期性的脉冲信号, 具有明确的高电平和低电平. 最常用的时钟是占空比 50% 的方形波. 时钟的单片机的脉搏, 搞懂时钟走向及关系, 对单片机的使用至关重要.

STM32 时钟

时钟树

STM32 的时钟系统以一种树状结构连接各个时钟源, 时钟分配和外设. 时钟树负责将所选的时钟源信号分配给处理器内核, 外设和总线. 根据不同的应用需求, 可通过时钟树配置不同的时钟频率和时钟源.

锁相环

锁相环 (Page-Locked Loop): PLL 是一种用于产生高频时钟信号的电子电路. 在 STM32 中, PLL 可以将内部或外部时钟源的频率倍增, 从而产生更高频率的时钟信号. PLL 的倍频系数和分频系数是可配置的, 使得开发者可以根据需求生成不同频率的时钟信号.

APB

APB (Advanced Peripheral Bus): STM32 微控制器通常有两个 APB 总线, 即 APB1 和 APB2. APB1 和 APB2 的时钟频率可以通过时钟树进行独立配置.

时钟树

STM32 时钟树

F1 系列时钟树

时钟源名称频率材料用途
高速外部振荡器 (HSE)4-16 MHz晶体/陶瓷SYSCLK/RTC
低速外部振荡器 (LSE)32.768 KHz晶体/陶瓷RTC
高速内部振荡器 (HSI)8 MHzRCSYSCLK
低速内部振荡器 (LSI)40 KHzRCRTC/IWDG
符号作用
时钟安全系统 (CSS)如果 HSE 启动失败, 切换到 HSI, 可进 NMI 中断
自由运行时钟 (FCLK)用于采样中断和调试模块计时, 休眠仍有效

F4 系列时钟树

时钟源名称频率材料用途
高速外部振荡器 (HSE)4-26 MHz晶体/陶瓷SYSCLK/RTC
低速外部振荡器 (LSE)32.768 KHz晶体/陶瓷RTC
高速内部振荡器 (HSI)16 MHzRCSYSCLK
低速内部振荡器 (LSI)32 KHzRCRTC/IWDG

F7 系列时钟树

时钟源名称频率材料用途
高速外部振荡器 (HSE)4-26 MHz晶体/陶瓷SYSCLK/RTC
低速外部振荡器 (LSE)32.768 KHz晶体/陶瓷RTC
高速内部振荡器 (HSI)16 MHzRCSYSCLK
低速内部振荡器 (LSI)32 KHzRCRTC/IWDG

H7 系列时钟树

时钟源名称频率材料用途
高速外部振荡器 (HSE)4-48 MHz晶振/陶瓷SYSCLK/RTC
低速外部晶振 (LSE)32.768 KHz晶体/陶瓷IWDG/RTC/AWU
高速内部振荡器 (HSI)64 MHzRCSYSCLK
低速内部振荡器 (LSI)32 KHzRCIWDG/RTC/SWU
高速内部振荡器 (HSI48)48 MHzRCUSB
低功耗内部振荡器 (CSI)4 MHzRCSYSCLK (低功耗)
辅助型时钟系统作用
时钟安全系统 (CSS)如果 HSE 启动失败, 切换到 HSI, 可进 NMI 中断
特殊时钟恢复系统 (CRS)可以实现自动调整振荡频率, 确保高精度时钟

系统时钟配置

系统时钟配置步骤

  1. 配置 HSE_Value: 告诉 HAL 库外部晶振频率, stm32xxxx_hal_conf.h
  2. 调用 SystemInit() 函数 (可选): 在启动文案中调用, 在 system_stm32xxxx.c 定义
  3. 选择时钟源, 配置 PLL: 通过 HAL_RCC_OscConfig() 函数设置
  4. 选择系统时钟源, 配置总线分频器: 通过 HAL_RCC_ClockConfig() 函数设置
  5. 配置扩展外设时钟 (可选): 通过 HAL_RCCEx_PeriphCLKConfig() 函数设置

外设时钟的使能和使能

当我们要使用某个外设时, 必须先使能该外设时钟.

HAL 库使能外设时钟的方法:

// 使能 GPIOA 时钟
__HAL_RCC_GPIOA_CLK_ENABLE();

HAL 库失能外设时钟的方法:

// 禁止 GPIOA 时钟
__HAL_RCC_GPIOA_CLK_DISABLE();

HAL_RCC_OscConfig() 函数

格式:

typdef struct
{	
	uint32_t Oscillator Type;  // 选择需要配置的振荡器
	uint32_t HSEState;  // HSE 状态
	uint32_t HSEPredivValue;  // HSE 预分频值
	uint32_t LSEState; // LSE 状态
	uint32_t HSIState;  // HSI 状态
	uint32_t HSICalibrationValue;  // HIS 校准值
	uint32_t LSIState;  // LSI 状态
	RCC_PLLInitTypeDef PLL;  // PLL 结构体
}RCC_OscInitTypeDef;

typedef struct
{
	uint32_t PLLState;  // PLL 状态
	uint32_t PLLSource;  // PLL 时钟源
	uint32_t PLLMUL;  // PLL 倍频系数
}RCC_PLLInitTypeDef;

例子:

HAL_StatusTypeDef Hal_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)

HAL_RCC_ClockConfig() 函数

格式:

typedef struct
{
	uint32_t ClockType;  // 要配置的时钟 (SYSCLK/HCLK/PCLK1/PCLK2)
	uint32_t SYSCLKSource;  // 系统时钟源
	uint32_t AHBCLKDivider; // AHB 时钟预分频系数
	uint32_t APB1CLKDivider;  // SPB1 时钟预分频系数
	uint32_t APB2CLKDivider;  // APB2 时钟预分频系数
}RCC_ClkInitTypeDef;

例子:

HAL_ClkInitTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)

设置 Flash:

uint32_t Flatency

#define FLASH_LATENCY_0 0x0000 0000U  // FLASH 0 个等待周期
#define FLASH_LATENCY_1 FLASH_ACR_LATENCY_0  // FALSH 1 个等待周期
#define FLASH_LATENCY2 FLASH_ACR_LATENCY_1  // FLASH 2 个等待周期
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。