我在高职教STM32——时钟系统与延时控制(1)

        大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正因如此,才有了借助 CSDN 平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思的教学设计分享出来,主要面向广大师生朋友,单片机老鸟就略过吧。欢迎点赞+关注,各位的支持是本人持续输出的动力,多谢多谢!

        众所周知,衡量一款处理器的性能,最重要的一个指标就是主频,对于STM32来说也不例外。主频的背后其实是一套复杂的时钟系统,而这套系统关乎所有外设的工作。因此,在我们继续深入学习之前,有必要了解STM32时钟系统的脉络,进而才能理解所有跟时间有关的机制和配置。其实,一开始我们用到的delay延时功能就是通过配置时钟系统实现的,现在是时候对它一探究竟了。

【学习目标】

  1. 认识STM32的系统时钟树,理解时钟的产生过程;
  2. 了解系统时钟配置函数的实现脉络;
  3. 知道SysTick定时器的地位和作用;
  4. 了解SysTick寄存器的功能;
  5. 理解延时函数的实现原理

        与STM32时钟有关的信息量不小,为了不让篇幅太长,本章打算分两个部分来讲解,本文是第一部分。

一、STM32的时钟系统

        时钟系统是CPU的脉搏,就像人的心跳一样,其重要性就不言而喻了。STM32的时钟系统比较复杂,不像51单片机一个系统时钟就可以解决一切。于是有人要问,采用一个系统时钟不是很简单吗?为什么STM32要有多个时钟源呢?首先,STM32的外设非常多,但并不是所有外设都需要系统时钟这么高的频率,比如看门狗以及RTC只需要几十kHz的时钟即可。其次,同一个电路,时钟越快功耗越大,同时抗电磁干扰能力也会越弱,所以对于较为复杂的MCU一般都是采取多时钟源的方法来解决这些问题。

        下面,让我们来看看STM32的时钟系统图吧,如图1所示。这张图是从《STM32中文参考手册》中摘过来的,初学者一看可能会无所适从,不知该从哪儿入手。别慌,我们在图上标注了一些序号(Ⅰ~Ⅴ、A~E)和一条主线(①~⑦),大家结合下面的分析,先好好领悟这些带有标注的地方,剩下的地方便可以触类旁通啦。

图1 STM32F103系列时钟框图

1.1 时钟源

        在STM32中,有五个时钟源:HSI、HSE、LSI、LSE、PLL,分别对应图1中的Ⅰ~Ⅴ。从时钟频率来分可以分为高速时钟源和低速时钟源,HIS、HSE和PLL是高速时钟,LSI和LSE是低速时钟。从来源可分为外部时钟源和内部时钟源,外部时钟源就是从外部通过接晶振的方式获取时钟源,其中HSE和LSE是外部时钟源,其他的是内部时钟源。下面我们依次来看每个时钟源的特点:

        I. HSI是高速内部时钟,采用RC振荡器,频率为8MHz。

        II. HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为 4MHz~16MHz,我们的开发板接的是12M的晶振。

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

        IV. LSE是低速外部时钟,接频率为32.768kHz的石英晶体,这个主要是RTC的时钟源,我们的开发板上没接这个晶振。

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

1.2 时钟分配

        上面我们简要概括了STM32的时钟源,那么这5个时钟源是怎么给各个外设以及系统提供时钟的呢?这里我们按照图1中A ~E的顺序进行讲解。

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

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

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

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

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

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

        2) 通过8分频后送给Cortex的系统定时器时钟,也就是SysTick了,它也是下一节要重点讲解的内容,延时的产生就跟它有关。

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

        4) 送给APB1分频器。APB1分频器有两路输出:一路供APB1外设使用 (PCLK1,最大频率36MHz),另一路送给定时器2~7使用。

        5) 送给APB2分频器。APB2分频器也有两路输出:一路供APB2外设使用 (PCLK2,最大频率72MHz),另一路送给定时器1和8使用。

        关于APB1和APB2总线的区别,主要在于挂载的外设不同,这一点我们在之前的章节中已经详细阐述过了,大家可以再翻看一遍,加深理解,这里就不再赘述了。

        在以上的时钟输出中,有很多是带使能控制的,例如AHB总线时钟、内核时钟、各种APB1外设、APB2外设等等。当需要使用某模块时,记得一定要先使能对应的时钟,我们在初始化GPIO时使用了 RCC_APB2PeriphClockCmd() 库函数,起的就是这个作用。

1.3 时钟主线

        现在来看图1中序号①~⑦的这条路径,我们称之为时钟主线。理解了这条主线,也就明白了STM32的系统时钟和各总线时钟是如何一步步确定的。而图中的其他路径,也就迎刃而解了。

        我们把区域①单独拎出来分析,如图2所示。来自于开发板上12MHz晶振的HSE信号,会到达一个梯形的模块,这其实是一个选择器,能够从多路输入信号中选择一路通过。可以看到,这个选择器的输入信号有两路,一路是HSE,另一路则是HSE/2。究竟选哪一路由PLLXTPRE信号决定,而该信号是时钟配置寄存器CFGR的第17位,固件库对其默认的配置是0。因此,经过区域①,得到了12MHz输出信号,该信号再进入区域②。

图2 时钟主线之HSE和PLL

        时钟线、对应寄存器及其功能在《STM32中文参考手册》6.3.2小节中有详细描述,上图只是把其中一部分整理后放在了一起,就是希望大家学会看图的方法,理解其中的来龙去脉。后面②~⑦的分析方法都是类似的,这里我们汇总如下:

        ● 区域②是PLL时钟源选择,默认选择的是HSE(12MHz)。

        ● 区域③是一个锁相环信号倍频器,它可以把来自PPLSRC的信号进行倍频处理,可选2倍~16倍。我们在配置工程模板的时候将其设置为了 6 倍频,这样就得到了12MHz*6 = 72MHz的PLLCLK,72MHz也是ST官方推荐的稳定运行时钟。这里也可设置更大的倍频系数得到更高的频率,但不建议超频。

        ● 区域④是系统时钟来源选择,可选HIS(内部高速时钟)、PLLCLK(锁相环时钟)、HSE(外部高速时钟),默认选择的是PLLCLK,这样得到的系统时钟SYSCLK与PLLCLK一致,也为72MHz。

        ● 区域⑤是AHB预分频器,系统时钟 SYSCLK经过这里分频后,得到AHB总线时钟HCLK,分频因子可以是1/2/4/8/16/64/128/256/512,默认配置为1,即HCLK = SYSCLK = 72MHz。STM32片上大部分外设的时钟都是经过HCLK 分频得到的。

        ● 区域⑥是APB2预分频器,HCLK经过这里分频后,得到APB2总线时钟PCLK2,分频因子可以是1/2/4/8/16,默认配置为1,即PCLK2 = HCLK = 72MHz。PCLK2属于高速的总线时钟,片上高速的外设就挂载在这条总线上,比如GPIO、USART1、TIM1/8等。

        ● 区域⑦是APB1预分频器,HCLK经过这里分频后,得到APB1总线时钟PCLK1,分频因子可以是1、2、4、8、16,默认配置为2,即PCLK1 = HCLK/2 = 36MHz。PCLK1属于低速的总线时钟,片上低速的外设就挂载在这条总线上,比如USART2/3/4/5、SPI2/3、I2C1/2等。

1.4 溯源系统时钟配置

        上面我们分析了时钟主线,这条主线确定了72MHz的系统时钟SYSCLK、72MHz的APB2总线时钟、36MHz的APB1总线时钟,其中所有的设置都通过时钟配置寄存器完成的。在实际开发中,我们并不需要亲自配置寄存器,固件库已经写好了配置函数,并且会在上电初始化中完成配置。接下来,我们一起追溯一下固件库里是如何实现系统时间配置的。

        如图3所示,STM32上电或复位后,先执行 startup_stm32f10x_hd.s 这个启动文件,该文件调用了 SystemInit() 函数(图中①)。SystemInit() 这个函数定义在 system_stm32f10x.c 中(图中②),可以看到了它又调用了 SetSysClock() 函数。继续进入 SetSysClock() 函数(图中③),是一堆条件编译结构,取决于定义了哪个宏。从图中④我们可以看到,  SYSCLK_FREQ_72MHz 这个宏被保留,所以 SetSysClockTo72() 这个函数(图中⑤)将被执行,而该函数内部就是按照上述时钟主线去配置寄存器的过程,源码比较复杂,感兴趣的读者可以去阅读和研究。

图3 系统时钟函数溯源

(第一部分完,共两部分) 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/754242.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

十步学习法,赋能程序员

大家好,我是码农先森。 引言 最近看了《软技能:代码之外的生存指南》这本书,对其中的 “十步学习法”。 有一些感触,所以将其中的内容记录并总结了下来,分享给大家。 程序员在学习成长的过程中,除了关注…

Andorid Studio SSL peer shut down incorrectly

当我们打开Android Studio创建项目的时候,发现Gradle构建项目,下载依赖的速度非常之慢,那么聪明的我们会设置Android Studio的Proxy代理,如下! 然后幸运的你可能下载速度会变快,但是也可能会有其他异常&…

3.x86游戏实战-寄存器

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 上一个内容:2.x86游戏实战-跨进程读取血量 寄存器说明: 寄存器是处理器的一部&…

【安全开发】内网扫描器

文章目录 前言现实现的功能较少后序开发会逐步加入简单漏洞探探测和代理功能。 一、开发过程1.项目结构2.main.go3.core模块3.1 scanner.go3.2 service.go 4.bruteforc4.1 bruteforce.go 二、使用步骤 前言 为什么要写这个? fscna被杀的概率太高(哪天二…

从单一到多元:EasyCVR流媒体视频汇聚技术推动安防监控智能升级

随着科技的飞速发展,视频已成为我们日常生活和工作中的重要组成部分。尤其在远程办公、在线教育、虚拟会议等领域,视频的应用愈发广泛。为了满足日益增长的视频需求,流媒体视频汇聚融合技术应运而生,它不仅改变了传统视频的观看和…

江山欧派杯2024全国华佗五禽戏线上线下观摩交流比赛在亳州开幕

6月28日,2024全国华佗五禽戏线上线下观摩交流比赛在安徽省亳州市开幕。 此次比赛是由安徽省亳州市文化旅游体育局和安徽省非物质文化遗产保护中心主办、亳州市华佗五禽戏协会(国家级非遗华佗五禽戏保护单位)和亳州市传统华佗五禽戏俱乐部&…

【数字基础设施1007】探索数字基础设施的影响:宽带政策变量数据集来了!

今天给大家分享的是国内顶级期刊2023年发表论文《数字基础设施与代际收入向上流动性——基于“宽带中国”战略的准自然实验》使用到的重要数据集——“宽带中国”政策变量数据、互联网发展指数以及工具变量(所在城市到杭州市的球面距离和到“八纵八横”政策节点城市…

2.最简单的hello驱动

写驱动最快的方法就是抄内核中的其他驱动&#xff0c;这里选择的是/Linux-4.9.88/drivers/char/mem.c 第一步新建一个hello_drv.c,把mem.c中的头文件都复制过来 #include <linux/mm.h> #include <linux/miscdevice.h> #include <linux/slab.h> #include <…

干货︱部分领域数字孪生白皮书及报告汇总(附下载)

在国家政策和市场需求的双轮驱动下&#xff0c;数字孪生技术越来越为人们所熟知。作为数字化的重要底层技术&#xff0c;数字孪生在优化各行各业产业布局、实现产业结构优化、打通生产上下游链条、迈向产业智能发展、推动行业高质量发展中发挥着重要作用。为了帮助广大读者朋友…

uni-app通过配置package.json实现环境变量、自定义条件编译

文章目录 前言官方提示使用方法微信小程序配置如下自定义条件编译使用方法 前言 uni-app 官方概括 官方文档 在开发web时&#xff0c;有时需要一套代码编译发布到不同的站点&#xff0c;比如主站和微信h5站。&#xff08;注意不是一套代码内部自适应不同浏览器&#xff0c;是真…

贾英才主任的中医探索之路

在北京崇文门中医医院&#xff0c;贾英才主任在中医领域的钻研从未停歇。他对药理的探究和药物搭配的研究&#xff0c;展现出了非凡的专注与执着。 贾英才主任常常埋首于浩瀚的中医典籍之中&#xff0c;逐字逐句地研读古代名医的论述&#xff0c;试图从那些古老的智慧中汲取精…

第十九课,编写并调用自定义函数

一&#xff0c;函数五大组成部分 因为其重要性故再此强调&#xff0c;参数列表可以为任意个数&#xff0c;返回值只能有一个&#xff08;请初学者暂时这样认为&#xff09; 特殊的&#xff0c;如果不需要返回结果&#xff0c;用None替代&#xff01; 二&#xff0c;编写自定义…

BUUCTF--WEB

首頁 - OWASP Top 10:2021 [极客大挑战 2019]EasySQL 类型:sql注入 使用万能密码 flag{f580db5b-c0c9-4b13-bfb6-adfa525c93f5} [极客大挑战 2019]Havefun 类型:代码审计 F12打开浏览器控制台 GET请求,在url添加参数/?cat=dog访问 返回flag{f60c7d5c-9f44-4e92-88c0…

操作系统期末复习(对抽象概念的简单形象化)

操作系统 引论 定义与基本概念&#xff1a;操作系统是计算机硬件与用户之间的桥梁&#xff0c;类似于家中的管家&#xff0c;它管理硬件资源&#xff08;如CPU、内存、硬盘&#xff09;&#xff0c;并为用户提供方便的服务&#xff08;应用程序执行、文件管理等&#xff09;。…

三星DRAM、NAND,“又双叒叕”带头涨价了

据韩国媒体《每日经济新闻》报道&#xff0c;三星电子计划在第三季度上调服务器DRAM和企业级NAND闪存的价格&#xff0c;涨幅预计在15%-20%&#xff0c;主要受人工智能(AI)需求激增的推动。这一举措有望提振公司下半年业绩。 据《经济日报》报道援引业内消息&#xff0c;由于厂…

数据资产赋能企业决策:通过精准的数据分析和洞察,构建高效的数据资产解决方案,为企业提供决策支持,助力企业实现精准营销、风险管理、产品创新等目标,提升企业竞争力

一、引言 在信息化和数字化飞速发展的今天&#xff0c;数据已成为企业最宝贵的资产之一。数据资产不仅包含了企业的基本信息&#xff0c;还蕴含了丰富的市场趋势、消费者行为和潜在商机。如何通过精准的数据分析和洞察&#xff0c;构建高效的数据资产解决方案&#xff0c;为企…

使用QGIS进行研究区域制图实战

目录 前言 一、QGIS的版本和数据介绍 1、关于QGIS版本 2、需要准备的数据 二、准备制图 1、制作全国区位图 2、矢量和遥感信息的编辑 三、出图编辑 1、设置主题信息 2、打印布局制作 3、美化地图 总结 前言 俗话说“一图胜千言”&#xff0c;在地理信息的领域中&…

利用代理IP实现高效大数据抓取的策略与技巧

在当今信息爆炸的时代&#xff0c;数据对于各行各业都至关重要。而数据的获取往往需要通过网络爬取。然而随着网络安全意识的提高和反爬虫机制的加强&#xff0c;传统的数据爬取方式可能会受到限制。在这种情况下&#xff0c;代理IP技术的应用就显得尤为重要。本文将探讨代理IP…

Java编程基本功大揭秘 | 详解深入分析Java线程池源码和底层原理,掌握实战技巧【1】

详解深入分析Java线程池源码和底层原理 文章大纲引言Java线程池概念及重要性 ThreadPoolExecutor类的概述ThreadPoolExecutor类的基本功能和作用**基本功能****核心作用** ThreadPoolExecutor主要构造函数及其参数继承关系链功能介绍ThreadPoolExecutor 构造器构造器参数构造器…

SysML与MBSE的关系

SysML与MBSE的关系 对于任何基于模型的系统工程 &#xff08;MBSE&#xff09; 方法&#xff0c;推荐的最佳实践是基于模型的语言、基于模型的工具、基于模型的流程和基于模型的架构框架的协同应用&#xff0c;如下图所示 系统架构四元组 图。经过十年将SysML应用于棘手的系统…