当前位置: 首页 > news >正文

OpenMCU(五):STM32F103时钟树初始化分析

概述

        本文主要描述了STM32F103初始化过程系统时钟的初始化,主要描述了系统时钟的初始化,AHB总线时钟,APB总线时钟等的初始化。

硬件板卡3d图

时钟树

STM32F103的时钟树,如下所示:

时钟源选择

从STM32F103的时钟树框图,我们可以看到:

1、有可选的1路高速外部时钟接口,作为系统时钟的时钟源;

2、1路32.768的可选低速时钟,作为系统RTC和watchdog的时钟源;

3、1路内部的可选8M 高速时钟,作为系统时钟的时钟源;

系统时钟选择

根据时钟树所示,可选的系统的时钟选择,如下所示:

1、内部8M的HSI直接作为系统的时钟源,如果使用HSI作为系统时钟源的话,最大SYSCLK只能输出到64MHz;

2、HSI或者HSE的通过PLL的倍频后,作为系统时钟源;

3、HSE的输出,直接作为系统的时钟源;

通过系统时钟源的来源描述,系统的时钟源可以根据硬件板卡的制作情况,进行选择;作者自己设计的PCB板子上,因为没有连接外部晶振,因此将HSI作为系统的时钟源选择。后续的时钟初始化代码分析,会讲解怎么将HSI设置为系统的时钟源;

其他外设时钟

根据STM32F103的时钟树,其他外设控制器的时钟的来源如下所示:

1、USB控制器的时钟,直接来源于PLLCLK,然后经过USB预分频,最终达到48M的时钟输出,作为USB控制器的时钟;

2、I2S音频控制器的时钟,直接来源于SYSCLK, 和SYSCLK的时钟相同;

3、SDIO, FSMC, HCLK 等时钟,直接来自于AHB总线的时钟输出;

4、剩余外设的时钟自于APB1或者APB2,这里不再这里详细描述;

时钟初始化设置

由于作者自己设计的硬件板子,使用了内部的8M作为整个CPU的时钟源,因此,下面以使用内部8M的高速时钟的情况,进行源码讲解,设置源码如下所示:

void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef clkinitstruct = {0};
  RCC_OscInitTypeDef oscinitstruct = {0};

  /* Configure PLL ------------------------------------------------------*/
  /* PLL configuration: PLLCLK = (HSI / 2) * PLLMUL = (8 / 2) * 16 = 64 MHz */
  /* PREDIV1 configuration: PREDIV1CLK = PLLCLK / HSEPredivValue = 64 / 1 = 64 MHz */
  /* Enable HSI and activate PLL with HSi_DIV2 as source */
  oscinitstruct.OscillatorType  = RCC_OSCILLATORTYPE_HSI;     /* HSI作为系统时钟源 */
  oscinitstruct.HSEState        = RCC_HSE_OFF;                /* 关闭HSE时钟 */
  oscinitstruct.LSEState        = RCC_LSE_OFF;                /* 关闭LSE时钟 */
  oscinitstruct.HSIState        = RCC_HSI_ON;                 /* 开启HSI时钟 */
  oscinitstruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  oscinitstruct.HSEPredivValue    = RCC_HSE_PREDIV_DIV1;
  oscinitstruct.PLL.PLLState    = RCC_PLL_ON;
  oscinitstruct.PLL.PLLSource   = RCC_PLLSOURCE_HSI_DIV2;
  oscinitstruct.PLL.PLLMUL      = RCC_PLL_MUL16;
  if (HAL_RCC_OscConfig(&oscinitstruct)!= HAL_OK)
  {
    /* Initialization Error */
    while(1);
  }

  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
     clocks dividers 将PLL的输出,作为系统时钟*/
  clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1;
  clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2;
  if (HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2)!= HAL_OK)
  {
    /* Initialization Error */
    while(1);
  }
}

        由于作者为了减少PCB板子的尺寸,因此在设计过程中,硬件上没有接外部晶振和32.768的低速晶振。因此只能使用内部HSI作为时钟源,但是在使用HSI作为时钟源时,系统的时钟最大只能设置到64MHz;

代码主要逻辑如下:

1、将HSI的晶振作为系统的晶振输入;

2、关闭HSE时钟源;

3、关闭LSE时钟源;

4、计算出SYSCLK = HSI /2 * PLL_MUl16 = 8/2 * 16 = 64M;

5、调用HAL_RCC_OscConfig()接口,设置系统时钟源;

6、选择PLLCLK的输出,最为系统时钟(64M);

总结

        本文主要描述了,在STM32F103 CPU初始化过程中,系统时钟的初始化。虽然,我们可以利用ST提供的上位机图形化工具进行时钟配置,简单的勾选就可以产生我们需要的代码。但是,作为一个嵌入式开发程序员,我觉得,还是有必要去分析源码,了解CPU的内部原理和HAL层代码,这样才能根据自己产品的实际需求情况,设计出更具有性价比的产品。

链接

yanl1229/STM32F103

相关文章:

  • 黑帽SEO之搜索引擎劫持-域名劫持原理分析
  • 银发浪潮下的智能护理革命:全球老龄化社会护理机器人发展研究
  • AI时代新坐标!火石会:应时而生,聚势而为
  • AI推理胜过人脑?思维模型!【34】长线思考思维模型
  • 普冉单片机PY32F002BF,使用adc内部参考电压VREFINT检测。
  • uniapp 微信小程序项目中 地图 map组件 滑动面板
  • 2025 年广东水利水电安全员考试:理论与实践融合攻略​
  • 通过redis缓存获取菜品数据
  • Docker学习--容器操作相关命令--docker events 命令
  • 【mapreduce】工作原理
  • livekit ICE连接失败的一些总结
  • 鬼泣:升龙系统
  • Linux-线程概念与线程控制的常用操作
  • 通过动态获取项目的上下文路径来确保请求的 URL 兼容两种启动方式(IDEA 启动和 Tomcat 部署)下都能正确解析
  • 深度解析算法之滑动窗口
  • 清晰易懂的Rust安装与配置教程
  • 【区块链安全 | 第十五篇】类型之值类型(二)
  • 在 RK3588 多线程推理 YOLO 时,同时开启硬件解码和 RGA 加速的性能分析
  • 【JavaEE】UDP数据报套接字编程
  • 傅里叶变换C++实现方式
  • 模仿 网站/百度极速版
  • 杭州认证网站建设/上海最专业的seo公司
  • 通州企业网站建设/中国最新消息
  • 做推广网站公司/免费域名怎么注册
  • 域名网站排名/seo研究协会
  • 动态网站建设步骤/网络营销工具介绍