STM32教程(五):定时器 您所在的位置:网站首页 STM32内部有几个定时器 STM32教程(五):定时器

STM32教程(五):定时器

2024-07-09 09:31| 来源: 网络整理| 查看: 265

我们前面讲完了GPIO与中断,之后的内容都会建立在这两点基础之上。

定时器是最重要的外设,是一切复杂程序的根基,对时间的精准测量与感知是人类做到的最伟大的事情之一,没有时间就没有智慧。

在了解定时器之前我们先来学习如何使用定时器。

打开CubeMX,创建一个新的工程,在 System Core 和 Timer 就能看到这个单片机的几乎所有可以使用的定时器资源:

此图是STM32F103C8T6的定时器资源

我们能看到有RTC以及TIM1~TIM4的定时器资源。其中RTC指的是实时时钟,TIM1~TIM4是定时器。对于M3架构STM32有如下的定时器划分我们可以在参考手册中查到:

看到这里你可能会疑惑我也没有那么多时钟啊?那是因为你买的型号没那么多资源,每一本手册都会写明本手册的适用范围比如我们在教程中看的这本支持的范围是:

在MSDN的PowerShell文档中有一句话“专家不一定总是知道答案,但是他们知道如何得到答案。”这是许多人都学不到的能力,在文档中是用这个小故事说明的:

MSDN的截图

回到正题,我们如何去配置时钟呢?

请跟着我一步一步的操作:

Step 1 : 打开System Core 找到 RCC 

我们看到这个里面有仨选项,分别是 High Speed Clock、Low Speed Clock、Master Clock Output。他们分别是 高速时钟、低速时钟、主时钟输出。

对于这几个时钟主要看自己的选择,一般而言都只用高速时钟。

2. Step 2: 点击下拉菜单选择 Crystal/Ceramic Resonator 

3. Step 3 : 进入时钟配置界面

点击这个按钮

4. Step 4 : PLL Source Mux 选择我们刚刚开启的HSE ,System Clock Mux选择 PLLCLK

这里了解一下 PLL Source Mux 和 System Clock Mux ,PLL Source Mux 是 PLL资源选择器,System Clock Mux 是系统时钟选择器。他们都能进行分频和倍频。其中值得我们了解的是 PLL 和 Mux 你可能会疑惑这不就是俩单词吗?事实上,他们的含义都是硬件。PLL 是锁相环的缩写 phase-locked loop ,Mux是多路选择器的缩写 multiplexer 。至于他们的结构和作用暂时不在这里展开,因为这会很啰嗦,而且目前我们也不需要知道,徒增烦恼。

5. Step 5 : 在 HCLK 中改写数值为72,至于为什么是72,那是因为一般而言时钟频率越高越好,CPU的主要性能指标之一。然后按下回车键,软件会自动帮我们选择好分频和倍频系数。

至此我们完成了时钟配置,可喜可贺啊!

接着我们来配置定时器,因为定时器属于外设,使用的是RCC的时钟源,所以刚刚只是前置,下面我们来配置定时器。

回到引脚设置界面,首先打开Timers

我们能看到 RTC ,TIM1,TIM2,TIM3,TIM4 5个定时器,事实上IWDG和WWDG也是定时器,他们叫做看门狗。他们的作用比较特殊暂时不在这里讲解。

现在我们点击TIM2,查看TIM2的配置界面:

我们从上往下介绍,Slave mode 就是从模式,一般我们用不到它,此处默认不开启,Trigger mode 是触发模式,选择你的触发源,和定时器中断有关,暂时用不到,默认不开启,Clock source选择定时的时钟源,有 disable,internal clock(内部时钟),ETR2 三个选项,一般我们使用internal clock。如果我们使用定时器的 PWM 功能,输入捕获功能则不必管这个选项默认不开启即可。下面依次四个就是这个定时器拥有的四个定时器通道。再接着往下就是组合通道也很少用,主要是用来处理一些特殊的需求,比如编码器。再接着往下看有两个灰了,如果有选项灰了一般是这几种情况,配置不正确、被占用、未下载对应的软件包。事实上我们在创建工程时自动下载的只是最基础的软件包。最后一个就是单脉冲模式。

至于我们想要拓展软件包可以在这里下载:

点击 Select Component 进行选择下载。

现在如果不考虑定时器频率的情况下我们已经完成了对于定时器的配置。但是该学还得学,下面我们来配置定时器的相关参数,我们这里配置一个1kHz的频率。

将 Prescaler 和 Counter Period 设置如图即可。

现在我们如何去检测我们设置的定时器是否正确工作呢?现在我们开启这个定时器的中断,用这个中断来控制一个引脚的输出。然后将引脚接上示波器就能观察到我们的定时器是否正确的工作。

步骤如下:

之后我们生成代码。

我们能在工程里看到新的东西,我们会发现一个tim的文件:

现在我们回到main文件来编写程序,在预定的 function 的位置编写中断回调函数,我们这次使用的函数是 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

对于定时器有很多中断回调函数,针对不同的中断事件预设,可以在 stm32f1xx_hal_tim.h 的 2069 行看到声明。

然后在main函数里开启定时器

注意和外设有关的程序都必须写在这个位置,或者说要写在 MX_XXX_Init();这个外设初始化函数后面。否则会出BUG。现在我们就可以构建工程上板测试了。

现在我们面临一个问题,示波器很贵,常见的仿真软件例如 Proteus 很大概率不支持STM32你对应型号的芯片,需要自己去下载固件包配置一大堆很烦的东西才能正常使用。事实上对于芯片的片内外设都可以在Keil里仿真,当然前提是支持这款芯片,需要注意的是不是所以芯片都支持的。具体支持哪些芯片仿真可以去查询keil官方的debug文档。

如果你想迅速的查看你的芯片是否支持仿真可以尝试以下步骤来查询。

Step 1:在 flie 菜单找到 Device Database 点击它

Step 2:进入界面之后,在 search 里输入你使用的芯片型号并选中,我们这里就是 STM32F103C8

如果你在下面的说明栏里找到 SVD的文件说明那么就是可以进行仿真的,仿真参数就是 SIM后面的内容,我们先记下来。

如何查询到这里就已经结束 了,下面我们来填写仿真参数打开设置

然后我们就可以进行软件仿真debug了。

下面我们来学习如何进行软件仿真:

Step 1:点击debug按键进入debug模式

Step 2:打开分析仪:

圈起来的就是

如果你在这里找不到那么也可在view的菜单栏内找到

Step 3:在分析仪的窗口内找到 Setup 点击

Step 4:进入界面后创建新的按钮创建新的通道,使用PORT指令指定你的引脚后按回车键完成创建

这里解释一下PORT指令,PORTx.y,x写端口y写引脚号,例子如图。

回车后如果弹出异常请检查你的在设置中填写的调试参数是否正确。

一些正常之后应当如图所示:

Step 5:选中你刚刚创建的通道,将 Display Type 改为bit,否则无法正确显示

color是用来指定在分析仪中显示的波形颜色的不必管他,之后关闭这个界面,点击RUN就能看到波形了如图

我来选定一个周期可以看到频率为500Hz,因为我们的引脚是1ms翻转一次,所以输出的频率应该为 1k/2 结果为 500Hz与我们观察到的结果一致

定时器正确的在工作。

下面我们来更仔细的来考察一下定时器,来回忆一下刚刚的种种疑点。

第一为什么我在配置时钟源的时候使用的是内部时钟(internal clock),而单片机使用的明明是外部高速时钟。

解答这个问题,需要我们打开参考手册关于TIM定时器的图来看:

这张图很重要经常使用

这里就写明了什么是内部时钟,其实这里的内部指的是CPU,说的是系统时钟或者说是挂载这个外设的APB总线的时钟。

第二设置TIM2定时器的属性都是什么意思?

从上到下解释一遍,PSC就是预分频器,对TIM定时器进行分频的。Counter Mode是计数模式、Counter Period 是自动重装载寄存器,internal Clock Division 是内部时钟分割系数, auto-reload preload 是自动重装载预加载,至此计数设置说完,然后是触发设置。

Master/Slave Mode 是主从模式,Trigger Event Selection 是触发事件选择。

下面我们来说明三个比较关键的属性 预分频器,自动重装载寄存器和预加载。

首先PSC和自动重装载都是16位寄存器,我们可以在参考手册里找到他们的描述

这也是为什么我们在配置时要对数字“-1”操作的原因,因为这些值会直接写进寄存器,而寄存器是从0开始计数的,所以必须“-1”才能保证正确。

PSC的作用是对输入计数器的时钟进行分频,让计数器以分频后的频率进行计数。而ARR寄存器的作用是储存用户指定的值,对计数器内的计数值和ARR寄存器储存的值进行比较,当计数器内的值大于等于ARR存储的值时对计数器进行清理,如果你开启了中断,那么CPU还会接受到一个更新中断事件(UG\U)来触发中断程序。

那么预加载是干什么的?和重装载有什么关系?

这里我们思考如下情形,当我们的ARR初始以装载500的数值运行一段时间后,我们需要变更ARR的值以另外一种频率执行中断程序,那么怎么办呢?如果你对时序的要求不严谨那么肯能没什么问题,但是我们需要一个很严格的时序呢?那就需要使能预加载。他的作用就是,当我们修改了ARR之后,ARR的值并不立即生效,而是只有在修改后产生过一次更新事件ARR的值才会在这一次之后生效。他对应的是CR1寄存器的ARPE:

本篇长度已经很长了,下一篇将详细介绍定时器的寄存器等内容。

如果你觉得本教程对你有帮助记得一键三连喵~

点个赞也行啊~



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有