目录

前言

一、看如下时钟树我们能发现STM32有5个时钟源

二、 STM32F103 时钟系统配置


前言

想要运用好一款单片机必须要知道微控制器原理性的东西,这样在对它进行应用的时候,才能得心应手明白它如何进行的工作。项目出问题时,也能在底层找到问题的源头和解决方案。STM32的时钟系统比51单片机的时钟系统要复杂很多,毕竟51单片机只有一个时钟系统。

从STM32参考手册上,我了解到STM32F103MCU有三种不同的时钟源可被用来驱动系统时钟(SYSCLK): HSI振荡器时钟 、HSE振荡器时钟 、PLL时钟。当不被使用时,任一个时钟源都可被独立地启动或关闭,由此优化系统功耗。

所以能够知道, STM32采取多种时钟源是为了减少时钟的功耗,在数字电子技术中:同一个电路,时钟越快它消耗的功率就越大,并且抗电磁场的干扰能力也就越弱,脉冲越不稳定。

一、看如下时钟树我们能发现STM32有5个时钟源

(参考正点原子的开发指南)

ⅰ、HSI 是高速内部时钟,RC 振荡器(在Multisim专栏里,对文氏桥电路进行了仿真,想详细了解可以去看一看),频率为 8MHz。

ⅱ、HSE 是高速外部时钟,可接石英/陶瓷谐振器(在Multisim专栏里,对石英晶体电路进行了仿真,想详细了解可以去看一看),或者接外部时钟源,频率范围为4MHz~16MHz。

ⅲ、LSI 是低速内部时钟,RC 振荡器,频率为 40kHz。独立看门狗的时钟源只能是 LSI,同 时 LSI 还可以作为 RTC 的时钟源。

ⅳ、LSE 是低速外部时钟,接频率为 32.768kHz 的石英晶体。这个主要是 RTC 的时钟源。

ⅴ、PLL 为锁相环倍频输出,其时钟输入源可选择为 HSI/2、HSE 或者 HSE/2。倍频可选择为 2~16 倍,但是其输出频率最大不得超过 72MHz。

时钟树

①、MCO 是 STM32 的一个时钟输出 IO(PA8),它可以选择一个时钟信号输出,可以选择为 PLL 输出的 2 分频、HSI、HSE或者系统时钟。这个时钟可以用来给外部其他系统提供时钟源。

②、 这里是 RTC 时钟源,从图上可以看出,RTC 的时钟源可以选择 LSI,LSE,以及 HSE 的 128 分频。

③、从图中可以看出 USB 的时钟是来自 PLL 时钟源。STM32 中有一个全速功能 的 USB 模块,其串行接口引擎需要一个频率为 48MHz 的时钟源。该时钟源只能从 PLL 输出端获取,可以选择为 1.5 分频或者 1 分频,也就是,当需要使用 USB 模块时,PLL 必须使能,并且时钟频率配置为 48MHz 或 72MHz。

④、 STM32 的系统时钟 SYSCLK,它是供 STM32 中绝大部分部件工作的时钟源。系统时钟可选择为 PLL 输出、HSI 或者 HSE。系统时钟最大频率为 72MHz, 当然你也可以超频,不过一般情况为了系统稳定性是没有必要冒风险去超频的。

⑤、是指其他所有外设了。从时钟图上可以看出,其他所有外设的时钟最终来源都是 SYSCLK。SYSCLK 通过 AHB 分频器分频后送给各模块使用。这些模块包括:

1、AHB 总线、内核、内存和 DMA 使用的 HCLK 时钟。

2、通过 8 分频后送给 Cortex 的系统定时器时钟,也就是 systick 。

3、直接送给 Cortex 的空闲运行时钟 FCLK。

4、送给 APB1 分频器。APB1 分频器输出一路供 APB1外设使用(PCLK1,最大频率 36MHz),另一路送给定时器(Timer)2、3、4 倍频器使用。

5、送给 APB2分频器。APB2分频器分频输出一路供 APB2 外设使用(PCLK2:最大频率 72MHz),另一路给定时器(Timer)1倍频器使用。

APB1 上面连接的是低速外设,包括电源接口、 备份接口、CAN、USB、I2C1、I2C2、UART2、UART3 等等,APB2 上面连接的是高速外设包 括 UART1、SPI1、Timer1、ADC1、ADC2、所有普通 IO 口(PA~PE)、第二功能 IO 口等。

二、 STM32F103 时钟系统配置

(都是根据STM32的寄存器进行编程的)

typedef struct /*寄存器*/

{

  __IO uint32_t CR;                //HSI,HSE,CSS,PLL等的使能和就绪标志位

  __IO uint32_t CFGR;           //PLL等的时钟源选择,分频系数设定

  __IO uint32_t CIR;               // 清除/使能 时钟就绪中断

  __IO uint32_t APB2RSTR;  //APB2线上外设复位寄存器

  __IO uint32_t APB1RSTR;   //APB1线上外设复位寄存器

  __IO uint32_t AHBENR;    //DMA,SDIO等时钟使能

  __IO uint32_t APB2ENR;   //APB2线上外设时钟使能

  __IO uint32_t APB1ENR;   //APB1线上外设时钟使能

  __IO uint32_t BDCR;        //备份域控制寄存器

  __IO uint32_t CSR;           //控制状态寄存器

} RCC_TypeDef;

1.SystemInit 初始化程序:

void SystemInit (void)
{/* Reset the RCC clock configuration to the default reset state(for debug purpose) *//* Set HSION bit */RCC->CR |= (uint32_t)0x00000001; //打开 HSION 位/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CLRCC->CFGR &= (uint32_t)0xF8FF0000;
#elseRCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */   /* Reset HSEON, CSSON and PLLON bits */RCC->CR &= (uint32_t)0xFEF6FFFF;// 复位 HSEON, CSSON 和 PLLON 位/* Reset HSEBYP bit */RCC->CR &= (uint32_t)0xFFFBFFFF; // 复位 HSEBYP 位/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */RCC->CFGR &= (uint32_t)0xFF80FFFF;//复位 CFGR 寄存器#ifdef STM32F10X_CL/* Reset PLL2ON and PLL3ON bits */RCC->CR &= (uint32_t)0xEBFFFFFF;/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x00FF0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;
#else/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)#ifdef DATA_IN_ExtSRAMSystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */
#endif /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers *//* Configure the Flash Latency cycles and enable prefetch buffer */SetSysClock();#ifdef VECT_TAB_SRAMSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}

SystemInit 主要做了如下三个方面工作: 1) 复位 RCC 时钟配置为默认复位值(默认开始了 HIS) 2) 外部存储器配置 3) 中断向量表地址配置。

2.SetSysClockTo72

将系统时钟频率设置为 72MHz 并配置 HCLK、PCLK2和 PCLK1 预分频器。

初始化之前首先通过宏定义定义系统时钟频率:#define SYSCLK_FREQ_72MHz  72000000

初始化之后的状态:

     SYSCLK         72MHz

     AHB                72MHz

     PCLK1           36MHz

     PCLK2           72MHz

     PLL                72MHz

初始化之后可以通过变量SystemCoreClock获取系统变量。如果SYSCLK=72MHz,那么变量SystemCoreClock=72000000。

static void SetSysClockTo72(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    /* Enable HSE */    RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}  if (HSEStatus == (uint32_t)0x01){/* Enable Prefetch Buffer */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 2 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    /* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;//HCLK2分频#ifdef STM32F10X_CL/* Configure PLLs ------------------------------------------------------*//* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz *//* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);/* Enable PLL2 */RCC->CR |= RCC_CR_PLL2ON;/* Wait till PLL2 is ready */while((RCC->CR & RCC_CR_PLL2RDY) == 0){}/* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL9);
#else    /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL *//* Enable PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Select PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    /* Wait till PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}}else{ /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */}
}

SetSysClockTo72 将系统时钟频率设置为 72MHz 并配置 HCLK、PCLK2和 PCLK1 预分频器。

主要通过查询STM32中文参考手册,找到相应的寄存器,明白各个代码的作用。

学习记录:STM32F103 时钟系统概述工作原理相关推荐

  1. 模电学习笔记 (一) 晶体三极管工作原理

    大家好,我是一名从事硬件电路设计的小工程师一名.我决心从今天开始撰写自己的博客,一方面是为了对知识进行总结记录,加深理解与认识,另一方面希望大家可以多多批评指正,同时结识更多志同道合的朋友,一起学习进 ...

  2. 计算机主板时钟,主板时钟电路工作原理

    主板时钟电路工作原理 时钟电路工作原理: DC3.5V电源经过二极管和L1(L1可以用0Ω电阻代替)进入分频器后,分频器开始工作,和晶体一起产生振荡.在晶体的两脚均可以看到波形.晶体的两脚之间的阻值在 ...

  3. 计算机时钟的工作原理,单片机的周期与系统时钟的工作原理

    我们先来理解几个比较重要的概念:时间周期.指令周期.机器周期,以及系统时钟的工作原理. 时钟周期: 时钟周期也叫振荡周期或晶振周期,即晶振的单位时间发出的脉冲数,一般有外部的振晶产生,比如12MHZ= ...

  4. 时钟服务器工作原理,Windows 时间服务的工作原理

    Windows 时间服务的工作原理 05/08/2018 本文内容 适用于:Windows Server 2016.Windows Server 2012 R2.Windows Server 2012 ...

  5. 学习小记 -- 线程池的工作原理

    线程池的五种状态: Running:能接受新任务,可以处理已经添加的任务. Shutdown:不接受新任务,可以处理已经添加的任务. Stop:不接受新任务,不处理已经添加的任务,并且中断正在处理的任 ...

  6. 时钟服务器工作原理,NTP时间服务器工作原理

    文章目录 [隐藏] NTP简介 NTP工作原理 NTP工作模式 NTP简介 NTP(Network Time Protocol, 网络时间协议)是由RFC 1305定义的时间同步协议,用来在分布式时间 ...

  7. 电路学习1——磁珠的工作原理、磁珠的分类、磁珠的模型、磁珠的参数、磁珠与电感的区别、磁珠的应用、磁珠的误区

    目录 简介 铁耗 磁滞损耗 磁珠归类 应用 对比 参数 用途 电源滤波 低通滤波器的设计 符号 关于单点接地 老师的主页:唐老师讲电赛 视频地址:磁珠的工作原理,磁珠的分类,磁珠的模型,磁珠的参数磁珠 ...

  8. Android SurfaceFlinger 学习之路(五)----VSync 工作原理

    原址 VSync信号的科普我们上一篇已经介绍过了,这篇我们要分析在SurfaceFlinger中的作用.(愈发觉得做笔记对自己记忆模块巩固有很多帮助,整理文章不一定是用来给别人看的,但一定是为加强自己 ...

  9. 【逆向学习记录】格式化字符串漏洞原理及其利用

    1 概述 前面学习完成栈溢出的漏洞利用,接下来最长用到的就是格式化字符串了,由于懒散,春节之前耽误的很多时间,这里统一整理一下 学习的过程中,主要参考文章: 格式化字符串利用小结 CTF WIKI 格 ...

最新文章

  1. powershell真香
  2. 暑期集训3:几何基础 练习题C: POJ - 1269
  3. Python 基础 函数
  4. STM32-SysTick定时器
  5. 数据结构与算法之二冒泡排序
  6. tensorflow sigmoid 如何计算训练数据的正确率_量化训练:Quantization Aware Training in Tensorflow(一)...
  7. Spring boot Jar和war运行差异
  8. 【转】计算机键盘功能键作用
  9. 返回上一视图,凸显一个视图,其他视图变模糊
  10. 文本分类之一:语言模型
  11. SQLSERVER 查询分析器快捷键
  12. CTF之MISC练习一
  13. 在MacOS系统下DMG文件显示压缩包无法双击安装解决办法
  14. hdu 5510 Bazinga (尺取法)
  15. 阿里滑块 某宝的x82y解决方法、x5sec
  16. ch01变量和数据结构
  17. html广告sdk,腾讯社交联盟广告
  18. 最新《JPA入门到精通JAVA进阶项目实战》
  19. pypptee获取城市监测站点历史空气质量数据
  20. 基于Android的地铁查询系统app

热门文章

  1. (转)MVS-OS390系统管理-大型服务器概述
  2. 数字孪生天然气站 3D 可视化,助力冬季天然气保供模式
  3. 深度Q学习神经网络(DQN)
  4. vim8.0 c++开发环境配置
  5. PCB设计铝电解电容中必须要点
  6. 洛必达法则讲解和例题
  7. pyhon的数据类型
  8. 在模拟器上安装时一直停在instaling apk
  9. Eclipse解决每次修改java代码或jsp代码服务器重启问题的解决办法
  10. DM数据库数据守护集群搭建