stm32hal的rcc
时间: 2024-12-29 14:27:15 浏览: 13
### STM32 HAL RCC 使用方法及配置教程
#### 初始化时钟源
在使用STM32微控制器时,通过HAL库管理重置和时钟控制(RCC)模块可以简化开发过程。为了设置系统的时钟频率和其他外设的时钟分配,通常会在`main.c`中的`SystemClock_Config()`函数内完成这些操作[^1]。
```c
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the CPU, AHB and APB busses clocks */
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;
RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK | 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;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
```
这段代码展示了如何利用宏定义来指定振荡器类型、PLL乘数以及预分频因子等参数,并调用`HAL_RCC_OscConfig()`来进行实际配置;接着调整AHB/APB总线与时钟关系并启用相应的闪存等待状态以匹配新的CPU速度[^2]。
#### 动态修改时钟树
除了静态设定之外,在某些应用场景下可能还需要动态改变当前使用的时钟源或其倍率。这可以通过编写特定的应用逻辑配合HAL API实现:
- `HAL_RCC_GetSysClockFreq()`: 获取系统时钟频率。
- `__HAL_RCC_PWR_CLK_ENABLE()`, `__HAL_RCC_PWR_CLK_DISABLE()`: 启用/禁用电源接口时钟。
- `HAL_RCCEx_PeriphCLKConfig()`: 配置外围设备专用时钟(如USB OTG FS, RNG等)。
对于更复杂的变更比如切换HSI到HSE作为主时钟,则需遵循官方文档给出的具体流程确保安全过渡而不影响正在运行的任务。
#### 外围功能使能与失能
当涉及到具体外设的操作前,往往也需要先打开对应的RCC时钟供应以便访问寄存器资源。例如要启动ADC转换之前应该有如下语句确保APB2上有关联此硬件单元的部分已被激活[^3]:
```c
// 开启 ADC 所属的 APB2 总线上的时钟
__HAL_RCC_ADC1_CLK_ENABLE();
// 如果涉及 DMA 控制的数据传输同样需要开启相应通道所在位置处的时钟供给
__HAL_RCC_DMA1_CLK_ENABLE();
```
上述命令会解锁对应位从而允许后续对该部分电路进行读写动作直至程序显式关闭为止(`__HAL_RCC_Xxx_CLK_DISABLE`)。
阅读全文