用时钟树了解HAL_RCC结构体

       STM32的HAL库是由可视化工具自动生成相关硬件参数设置代码,为了了解学习时钟树的配置我用ST官方提供的时钟树图纸和两段小代码学习RCC部分结构体。请大家批评指导。

用HSI输出最大频率的时钟信号

首先上时钟树

根据标题我们在时钟树上选出为了输出最大频率的时钟信号所需要经过的路径和要设置的参数。

首先我们选择内部高速时钟源HSI,有两条路径,路径1经过/2分频来到PLLSRC,路径2直接到SW

为了满足最高频率选择路径1,倍率选择16倍,频率64MHz,通过PLLCLK进入SW后选择AHB为/1分频,这时SYSCLK上时钟频率为64MHz,小于72MHz。

我们配置HCLK、APB1、APB2,HCLK最大72MHz,64MHz小于满足要求,APB1选择倍率/2频率为32MHz,小于36MHz满足要求,APB2倍率选择/1频率为64MHz,小于72MHz满足要求

RCC_OscinitTypeDef结构体

首先我们建立RCC_OscinitTypeDef结构体变量CC_OscinitType —— 配置结构体成员OscillatorType为RCC_OSCILLATORTYPE_HSI —— 配置结构体变量HSIState为RCC_HSI_ON —— 配置结构体变量HSICalibrationValue为默认值RCC_HSICALIBRATION_DEFAULT —— 配置PLL结构体变量PLLState为RCC_PLL_ON —— 配置PLL结构体变量PLLSource为RCC_PLLSOURCE_HSI_DIV2—— 配置PLL结构体变量 PLLMUL为RCC_PLL_MUL16

代码如下

RCC_OscinitTypeDef RCC_OscinitType;

RCC_OscinitType.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscinitType.HSIState = RCC_HSI_ON;
RCC_OscinitType.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscinitType.PLL.PLLState = RCC_PLL_ON;
RCC_OscinitType.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
RCC_OscinitType.PLL.PLLMUL = RCC_PLL_MUL16;
HAL_RCC_OscConfig(&RCC_OscInitType);

这样我们完成了红色框图内的红色路径设置

RCC_ClkInitTypeDef结构体

建立RCC_ClkInitTypeDef结构体变量RCC_ClkInitType —— 设置结构体变量ClockType为全部选项 —— 设置结构体变量SYSCLKSource为RCC_SYSCLKSOURCE_HSI —— 设置结构体变量AHBCLKDivider为RCC_SYSCLK_DIV1 —— 设置结构体变量APB1CLKDivider 为RCC_HCLK_DIV2——设置结构体变量APB2CLKDivider为RCC_HCLK_DIV1

代码如下

RCC_ClkInitTypeDef RCC_ClkInitType;

RCC_ClkInitType.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitType.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitType.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitType.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitType.APB2CLKDivider = RCC_HCLK_DIV1;

HAL_RCC_ClockConfig(&RCC_ClkInitType);

这样我们完成了全部的设置

最终代码

void RCC_HSI_maxInit(void){

    RCC_OscinitTypeDef RCC_OscinitType;
    RCC_ClkInitTypeDef RCC_ClkInitType;

    RCC_OscinitType.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscinitType.HSIState = RCC_HSI_ON;
    RCC_OscinitType.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscinitType.PLL.PLLState = RCC_PLL_ON;
    RCC_OscinitType.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
    RCC_OscinitType.PLL.PLLMUL = RCC_PLL_MUL16;
    HAL_RCC_OscConfig(&RCC_OscInitType);

    RCC_ClkInitType.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitType.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    RCC_ClkInitType.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitType.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitType.APB2CLKDivider = RCC_HCLK_DIV1;
    HAL_RCC_ClockConfig(&RCC_ClkInitType);
}

用HSE输出最大频率的时钟信号

同理我们根据路径和两个表格编写如下代码

void RCC_HSE_maxInit(void){

    RCC_OscinitTypeDef RCC_OscinitType;
    RCC_ClkInitTypeDef RCC_ClkInitType;

    RCC_OscinitType.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscinitType.HSEState = RCC_HSE_ON;
    RCC_OscinitType.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
    RCC_OscinitType.PLL.PLLState = RCC_PLL_ON;
    RCC_OscinitType.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscinitType.PLL.PLLMUL = RCC_PLL_MUL4;

    RCC_ClkInitType.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitType.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    RCC_ClkInitType.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitType.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitType.APB2CLKDivider = RCC_HCLK_DIV1;
    HAL_RCC_ClockConfig(&RCC_ClkInitType);
}

表格下载

### STM32 HAL中 `__HAL_RCC_PWR_CLK_ENABLE()` 的作用 `__HAL_RCC_PWR_CLK_ENABLE()` 是一个宏定义,用于启用电源 (PWR) 外设的时钟。在 STM32 微控制器中,许多外设的功能都需要先使能其对应的时钟才能正常使用。对于 PWR 控制器而言,这个宏的作用就是打开 PWR 模块的时钟供应,从而允许后续对该模块寄存器的操作[^1]。 此功能通常被用来管理低功耗模式下的各种特性,比如待机模式、停止模式等。如果未调用 `__HAL_RCC_PWR_CLK_ENABLE()` 来启动 PWR 时钟,则尝试访问任何与 PWR 相关的寄存器可能会失败或引发异常行为。 #### 配置后备区域时钟 后备区域(Backup Domain)包含了 RTC 和一些备份寄存器,在系统复位甚至掉电情况下也能保持数据不丢失。为了配置并使用这些资源,除了需要开启上述提到的 PWR 时钟之外,还需要进一步处理如下事项: 1. **解锁后备域** 后备域默认处于锁定状态以保护其中的数据免受意外修改。因此,在更改任何与此有关的内容前需执行解琐动作。这可以通过调用 `HAL_PWR_EnableBkUpAccess()` 实现[^2]。 2. **初始化RTC** 接下来要做的便是设定实时时钟 (Real-Time Clock),它依赖于 LSE 或者其他指定作为 RTC 输入信号源的振荡器频率。这里可以利用到前面提及过的 `HAL_RTC_Init()` 及关联的时间/日期结构体填充过程[^3]。 3. **选择合适的时基源给定至 RTC** 使用函数如 `__HAL_RCC_RTC_CONFIG()` 设置 RTC 所使用的具体时钟源选项,并确认所选路径已激活相应外部晶体驱动电路(若是基于 LSE 的话)。另外记得通过命令像 `__HAL_RCC_RTC_ENABLE()` 开启通往 RTC 单元的实际时钟供给线路[^4]。 以下是实现以上描述逻辑的一个简单代码片段示例: ```c // Enable Power clock and unlock Backup domain access. __HAL_RCC_PWR_CLK_ENABLE(); HAL_PWR_EnableBkUpAccess(); // Configure the system clocks for RTC usage. __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE); __HAL_RCC_RTC_ENABLE(); // Initialize RTC with default parameters. RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef sDate = {0}; sTime.Hours = 0; sTime.Minutes = 0; sTime.Seconds = 0; sDate.WeekDay = RTC_WEEKDAY_MONDAY; sDate.Month = RTC_MONTH_JANUARY; sDate.Date = 1; sDate.Year = 0; if(HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN)!= HAL_OK){ Error_Handler(); } if(HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN)!= HAL_OK){ Error_Handler(); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值