详解STM32基础定时器
知晓编程 2022-09-28

定时器最基本的功能就是定时处理事情。比如定时发送USART数据、定时采集AD数据、定时检测IO口电位、还可以通过IO口输出波形等。可以实现非常丰富的功能。定时器是一个很强大的外设,不同行业使用的方式不同,知识面很广。

0 1 定时器介绍

首先我们可以在STM32F207数据手册找到定制器的资源,从下图可以看到STM32F207一共10个通用定时器,2个高级定时器,2个基本定时器。

不同定时器的区别

STM32F207 的用户参考手册中可以看到定时器的基本框图,下图是定时器 1&8 的看图。

由上图看出,不同寄存器具有不同的参数,位数的区别,计数模式的区别,DMA请求的区别,通道得的区别,互补输出的区别和其他。在具体项目中选择哪个定时器,需要看具体的应用场景。下文主要讲解定时器的基础定时功能,选择定时器3。其他定时器原理是相同的,理解定时器3的定时功能,其他定时器也就能理解了。对于STM32系列的单片机,外设基本都是一致的,并且其他家的MCU也是类似的,国内的有兆易创新、新唐科技、上海灵动微电子等等。

0 2 时钟源

定时器基本定时功能框图。

①CK_PSC定时器时钟TIMxCLK,经APB1预分频器后分频提供。

定时器时钟经过PSC 预分频器之后,即CK_CNT,用来驱动计数器计数。

计数器CNT 是一个16 位的计数器,向上,向下,向上/下计数模式,最大计数值为65535。当计数达到自动重装载寄存器的时候产生更新事件,并清零从头开始计数。

自动重装载寄存器ARR 是一个16位的寄存器,这里面装着计数器能计数的最大数值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断。

定时器说白了就是个计数器,就像我们用心跳粗略估算时间一样,心脏跳动粗略可以认为是1s,那么我们计时60次心跳就过了60秒。其中CK_CNT时钟就类似心跳,CNT计数器就类似心跳次数。举一个极端简单的例子,我们要实现60秒定时,CK_CNT1s,我们设置CNT计数器向上计数开启中断,因为只有溢出时,也就是计数到65535时才会有中断,那么我们设置CNT计数器为65535-60=65475,开始及时,那么60秒后就会产生中断。我们设置自动重装载寄存器ARR也为65475,当CNT计数器溢出时,自动重装载寄存器ARR就会自动装载到CNT计数器中,就能实现自动循环定时60秒。

经过上面分析,精确定时的关键在于CK_CNT的频率,而CK_CNT是由定时器时钟分频而来的。那么我们就要知道timer3的定时器时钟。我们就要看时钟系统部分,具体看文章《STM32F207时钟系统解析》,这篇文章主要讲解了系统的120M时钟如何从外部的25M的晶振得到的。其中说到APB外设时钟的问题。

定时器在APB定时器时钟下,具体在APB1还是在APB2时钟下我们可以从STM32F207数据手册上看到,图片名字STM32F20xblock diagram

从上文我们看timer3是在APB1下的。

那么我们来分析APB1的频率

从上图看出,APB1定时器的从系统120M时钟(系统时钟可配置的,我们使用默认的120M时钟)经过AHB分频,APB分频得到的。

在这里说上图红框中的“错误”,萌新可能不太理解。首先手册中少了个右括号。修改后应该为:





if(APBx presc == 1) X1else X2

也就是说

APB分频系数如果是1,频率不变,APB输出的频率就是APB下面时钟的频率。

APB分频系数不是1,频率X2APB输出的频率乘以2APB下面时钟的频率。


下面我们分析APB1时钟,从system_stm32f2xx.c中的SetSysClock函数中如下









/* HCLK = SYSCLK / 1*/RCC->CFGR |= RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK / 2*/RCC->CFGR |=RCC_CFGR_PPRE2_DIV2; /* PCLK1 = HCLK / 4*/RCC->CFGR|= RCC_CFGR_PPRE1_DIV4;

可以看到AHB分频系数是1APB1分频系数是4

timer3的时钟为120M/1/4*2= 60MHZ

这里有个疑问,ST提供的system_stm32f2xx.c注释为什么是HCLKPCLK2PCLK1,却没有上文提到的APBAHB字眼,具体看下我之前写过的文章《STM32F207时钟系统解析》。

其实我们出了分析代码,system_stm32f2xx.c文件头也是有注释的,方便查看。

当然,这要求我们的外部晶振是25M的,且system_stm32f2xx.c是没有被修改过的,如果大家需要修改这个文件单片机超频运行,建议把文件头的注释修改,养成一个良好的习惯。


0 3 时基单元

可编程高级定时器控制模块主要是一个带有相关自动重载16位计数器。这个计数器可以向上计数,向下计数或者交替递增和递减计数。计数器时钟可以通过一个分频器分频。

计数器的自动重载寄存器和预分频寄存器可以通过软件读写。即使当计数器正在运行也可以读写。

时基单元包括

  1. 计数器寄存器 (TIMx_CNT)

  2. 预分频器寄存器 (TIMx_PSC)

  3. 自动重载寄存器 (TIMx_ARR)

  4. 重复计数器寄存器 (TIMx_RCR)

自动重载寄存器是预装载的。从自动重载寄存器写入或读取会访问预装载寄存器。预装载寄存器的内容既可以直接传送到影子寄存器,也可以在每次发生更新事件(UEV)时传送到影子寄存器,这取决于TIMx_CR1 寄存器中的自动重载预装载使能位(ARPE)。当计数器达到上溢值(或者在递减计数时达到下溢值)并且TIMx_CR1 寄存器中的UDIS 位为0时,将发送更新事件。该更新事件也可由软件产生。

计数器由预分频器输出CK_CNT 提供时钟,仅当TIMx_CR1 寄存器中的计数器启动位(CEN)1 时,才会启动计数器。

预分频器说明

预分频器可对计数器时钟频率进行分频,分频系数介于1 65536 之间。该预分频器基于TIMx_PSC寄存器中的16 位寄存器所控制的16位计数器。由于该控制寄存器具有缓冲功能,因此可对预分频器进行实时更改。而新的预分频比将在下一更新事件发生时被采用

下图以一些示例说明在预分频比实时变化时计数器的行为。

预分频器分频由1 变为2 时的计数器时序图

预分频器分频由1 变为4 时的计数器时序图

0 4 计数模式

向上计数模式

在向上计数模式中,计数器从0增加到自动重载值(TIMx_ARR寄存器的值),然后从0重新开始并产生一个计数器溢出事件。

如果使用重复计数器,则当递增计数的重复次数达到重复计数器寄存器中编程的次数加一次(TIMx_RCR+1)后,将生成更新事件(UEV)。否则,将在每次计数器上溢时产生更新事件。

TIMx_EGR寄存器的UG位置1通过软件或使用从模式控制器时,也将产生更新事件。

通过软件将TIMx_CR1寄存器中的UDIS位置1可禁止UEV事件。这可避免向预装载寄存器写入新值时更新影子寄存器。在UDIS位写入0之前不会产生任何更新事件。不过,计数器和预分频器计数器都会重新从0开始计数(而预分频比保持不变)。此外,如果TIMx_CR1寄存器中的URS位(更新请求选择)已置1,则将UG位置1会生成更新事件UEV,但不会将UIF标志置1(因此,不会发送任何中断或DMA请求)。这样一来,如果在发生捕获事件时将计数器清零,将不会同时产生更新中断和捕获中断。

发生更新事件时,将更新所有寄存器且将更新标志(TIMx_SR寄存器中的UIF位)置1取决于URS位)

  1. 重复计数器中将重新装载TIMx_RCR寄存器的内容

  2. 自动重载影子寄存器将以预装载值 (TIMx_ARR) 进行更新

  3. 预分频器的缓冲区中将重新装载预装载值(TIMx_PSC寄存器的内容)

计数器时序图,1 分频内部时钟

计数器时序图,2 分频内部时钟

从上面两图看出,中断标志是需要软件清除的

计数器时序图,ARPE=0 时更新事件(TIMx_ARR 未预装载)

从上面两图看出,向上计数,还没有到达0x36,就把自动重载寄存器修改为0x36,就会在计数到0x36时产生动作。

计数器时序图,ARPE=1 时更新事件(TIMx_ARR 预装载)

从上面两图看出,向上计数,还没有到达0x36,就把自动重载预装载寄存器修改为0x36,就不会在计数到0x36时产生动作,会在这个时将自动重载预装载寄存器值赋给自动重载影子寄存器。

向下计数模式

在向下计数模式中,计数器从自动重载值(TIMx_ARR寄存器的值)向下计数到0,然后从自动重载值(重新开始并产生一个计数器溢出事件。

如果使用重复计数器,则当递减计数的重复次数达到重复计数器寄存器中编程的次数加一次(TIMx_RCR+1)后,将生成更新事件(UEV)。否则,将在每次计数器下溢时产生更新事件。

TIMx_EGR 寄存器的UG 位置1(通过软件或使用从模式控制器)时,也将产生更新事件。

通过软件将TIMx_CR1 寄存器中的UDIS 位置1 可禁止UEV 更新事件。这可避免向预装载寄存器写入新值时更新影子寄存器。在UDIS 位写入0之前不会产生任何更新事件。不过,计数器会重新从当前自动重载值开始计数,而预分频器计数器则重新从0 开始计数(但预分频比保持不变)。

此外,如果TIMx_CR1 寄存器中的URS 位(更新请求选择)已置1,则将UG 位置1 会生成更新事件UEV,但不会将UIF 标志置1(因此,不会发送任何中断或DMA 请求)。这样一来,如果在发生捕获事件时将计数器清零,将不会同时产生更新中断和捕获中断。

发生更新事件时,将更新所有寄存器且将更新标志(TIMx_SR 寄存器中的UIF 位)置1(取决于 URS 位):

  1. 重复计数器中将重新装载 TIMx_RCR 寄存器的内容

  2. 预分频器的缓冲区中将重新装载预装载值( TIMx_PSC 寄存器的内容)

  3. 自动重载活动寄存器将以预装载值( TIMx_ARR 寄存器的内容)进行更新。注意,自动重载寄存器会在计数器重载之前得到更新,因此,下一个计数周期就是我们所希望的新的周期长度

以下各图以一些示例说明当TIMx_ARR=0x36 时不同时钟频率下计数器的行为

计数器时序图,1 分频内部时钟

计数器时序图,2 分频内部时钟

计数器时序图,未使用重复计数器时更新事件

中央对齐(向上/向下计数模式)

在中心对齐模式下,计数器从0 开始计数到自动重载值(TIMx_ARR 寄存器的内容)-1,生成计数器上溢事件;然后从自动重载值开始向下计数到1 并生成计数器下溢事件。之后从0开始重新计数。

TIMx_CR1 寄存器中的CMS位不为“00”时,中心对齐模式有效。将通道配置为输出模式时,其输出比较中断标志将在以下模式下置1,即:计数器递减计数(中心对齐模式1CMS=“01”)、计数器递增计数(中心对齐模式2CMS =“10”)以及计数器递增/递减计数(中心对齐模式3CMS =“11”)。

在此模式下,TIMx_CR1 寄存器的DIR 方向位不可写入值,而是由硬件更新并指示当前计数器方向。

每次发生计数器上溢和下溢时都会生成更新事件,或将TIMx_EGR 寄存器中的UG 位置1(通过软件或使用从模式控制器)也可以生成更新事件。这种情况下,计数器以及预分频器计数器将重新从0 开始计数。

通过软件将TIMx_CR1 寄存器中的UDIS 位置1 可禁止UEV 更新事件。这可避免向预装载寄存器写入新值时更新影子寄存器。在UDIS 位写入0 之前不会产生任何更新事件。不过,计数器仍会根据当前自动重载值进行递增和递减计数。

此外,如果TIMx_CR1 寄存器中的URS 位(更新请求选择)已置1,则将UG 位置1 会生成UEV 更新事件,但不会将UIF 标志置1(因此,不会发送任何中断或DMA 请求)。这样一来,如果在发生捕获事件时将计数器清零,将不会同时产生更新中断和捕获中断。

发生更新事件时,将更新所有寄存器且将更新标志(TIMx_SR 寄存器中的UIF 位)置1(取决于URS 位):

  1. 重复计数器中将重新装载 TIMx_RCR 寄存器的内容

  2. 预分频器的缓冲区中将重新装载预装载值( TIMx_PSC 寄存器的内容)

  3. 自动重载活动寄存器将以预装载值( TIMx_ARR 寄存器的内容)进行更新。注意,如果更新操作是由计数器上溢触发的,则自动重载寄存器在重载计数器之前更新,因此,下一个计数周期就是我们所希望的新的周期长度(计数器被重载新的值)。

以下各图以一些示例说明不同时钟频率下计数器的行为

计数器时序图,1 分频内部时钟,TIMx_ARR = 0x6

计数器时序图,2 分频内部时钟

计数器时序图,ARPE=1 时的更新事件(计数器下溢)

计数器时序图,ARPE=1 时的更新事件(计数器上溢)

0 5 基础定时代码

10ms中断配置代码

关于设置分频值

TIM3CLK = 2 * PCLK1=2*HCLK / 4= HCLK / 2 = SystemCoreClock /2=60MHZ

所以下图红框内就是TIM3CLK

这里的值是分频系数=TIM3CLK/定时器实际频率,所以定时器频率是10000,也就是说除数就是定时器频率。一个clk1/10000s。定时时间=1/10000*定时器重载值。根据上面的配置,定时器重载值是100,也就是定时器中断周期是=1/10000*100=0.01s=10ms,也就是100HZ

如果在定时器翻转LED灯,那么LED灯闪烁频率是50Hz

上面的的分频值当然可以直接赋值5999,如果想修改为定时器频率为1000,那么还要重新计算。如果按照上面的写法,直接将除数修改为1000即可。

看到这里大家会有疑问,给的重载值明明是99,分频率值也减去1。下面将说明分频值和自动重载周期值都需要减去1的原因。

自动重载值:因为从0开始计算,赋值10,从0开始计数到1011次。

分频值:TIMx_PSC寄存器有以下描述。

特别说明

时钟分频因子


TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV2;

其实仔细看过技术手册后发现这句话与PWM输出实验其实是没关系的,这句话是设置定时器时钟(CK_INT)频率与数字滤波器(ETRTIx)使用的采样频率之间的分频比例的(与输入捕获相关),0表示滤波器的频率和定时器的频率是一样的。

首先这个colck_division时钟分割系数并不是对定时器的时钟频率进行分割。我们都知道输入捕获模式下有一个数字滤波器,这个数字滤波器可以通过配置寄存器改变他的采样频率,从而将一些频率滤除。

具体细节在输入捕获中详解。

我们也可以根据定时器的计数器的特性,使用查询计数器的方法实现精确延时,具体请看《STM32延时函数的四种方法》。

本文源自微信公众号:知晓编程,不代表用户或本站观点,如有侵权,请联系nick.zong@aspencore.com 删除!

声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 【立即预约】Keysight直播:搞懂介电常数那些事儿


  • 相关技术文库
  • 单片机
  • 嵌入式
  • MCU
  • STM
  • 基于C51单片机实现汽车座椅自动控制系统的软硬件设计

    引言 随着人们生活水平的提高,对汽车座椅的舒适性要求也越来越高,要求对汽车座椅地调节能够更加简单、方便、快捷。目前,汽车座椅位置的调节多采用基于手动调节方式的机械和电动控制两种方式。汽车座椅位置的调节...

    2小时前
  • MCS51单片机程序设计时堆栈的计算方法解析

    用C语言进行MCS51系列单片机程序设计是单片机开发和应用的必然趋势。Keil公司的C51编译器支持经典8051和8051派生产品的版本,通称为Cx51。应该说,Cx51是C语言在MCS51单片机上的扩展,既有C语言的共性,又有它自己...

    2小时前
  • 51单片机定时器工作原理及用法

    TMOD : 控制定时器的工作方式。8个bit,高四位 bit 控制 T1,、低四位 bit 控制 T0。因为定时器有4种工作方式;TMOD = 0x00(工作方式0),TMOD = 0x01(工作方式0),TMOD = 0x02(工作方式2),TMOD = 0x03(工作方式3)。...

    2小时前
  • 51单片机学习单片机之路总结

    学习单片机有一学期了,现在也由51转到STM32了。一直想对51的学习做一个总结。也希望对别人有一些启发。也给后学者提供一些建议。当然本文是我对自己学习过程的总结,若有不对的地方,还请高手指出。 我想,再看本...

    2小时前
  • hot51增强型单片机开发板原理图

    功能要求: 一):绿灯25s倒计时,绿灯过度红灯有5s黄灯时间,红灯25s后直接跳绿灯。 二):按键按下模拟闯红灯输入,产生5s蜂鸣器鸣叫。 开发环境: 软件:Keil uVision4 硬件:HOT51增强型单片机开发板 程序代码:...

    昨天
  • 51单片机的延时子程序

    延时程序在单片机编程中使用非常广泛,但一些读者在学习中不知道延时程序怎么编程,不知道机器周期和指令周期的区别,不知道延时程序指令的用法, ,本文就此问题从延时程序的基本概念、机器周期和指令周期的区别和联系...

    昨天
  • 什么是Flash盘?Flash盘的结构是什么样的?

    Flash是大家常使用的存储之一,对于Flash,大家或多或少有所了解。上篇文章中,小编对Flash闪存的类型有所介绍。为继续增进大家对Flash的认识,本文将对Flash盘、Flash盘结构以及Flash读写操作予以介绍。如果你对本...

    昨天
  • 深谈嵌入式系统,嵌入式系统是如何组成的?

    嵌入式系统在生活中有诸多应用,大家对于嵌入式系统或多或少有所耳闻。在前两篇文章中,小编对嵌入式系统进行过详细介绍。为继续增进大家对嵌入式系统的认识,本文将对嵌入式系统的组成加以说明。如果你对嵌入式系...

    06-27
  • 嵌入式系统秘籍共享,最全嵌入式系统解析

    嵌入式系统的应用十分广泛,因此越来越多的人学习嵌入式系统。由此,在学习嵌入式系统之前,我们应当对嵌入式系统具备一些认识。所以在本文余下部分,小编将对嵌入式系统进行全面解析。如果你对嵌入式系统具有兴趣...

    06-27
  • 51单片机超声波测距程序详解

    51单片机超声波测距程序详解 超声波四通道测距:超声波测距实现分为三大块: 其一是12864带字库的液晶驱动程序: 代码如下: /////////////////12864驱动程序/////////////////////////// //1写数据 void WriteDat...

    06-25
  • 51系列单片机的引脚图

    51系列单片机的引脚图 端子介绍 l P0.0~P0.7 P0口8位双向口线(在引脚的39~32号端子)。 l P1.0~P1.7 P1口8位双向口线(在引脚的1~8号端子)。 l P2.0~P2.7 P2口8位双向口线(在引脚的21~28号端子)。 l P3.0~P3.7 P2口8...

    06-25
  • 51单片机串口通信需要加超时中断吗?

    接收数据时,超过一定时间就算出错. 这个超时的时间是单片机自己算出的吗?超时的时间是由编程序的人定的,他定多长就多长从一段程序开始 实现电脑向 单片机发送一些数据,单片机返回Iget +数据 #include #define u...

    06-25
下载排行榜
更多
评测报告
更多
EE直播间
更多
广告