基本定时器(STM32F407)

1、基本定时器简介

STM32F407 有两个基本定时器,即 TIM6 和 TIM7,它们的功能完全相同,资源是完全独立的, 可以同时使用。

基本定时器主要特性

①16位递增计数器(计数值:0~65535);

②16位预分频器(分频系数:1~65536);

③可用于触发DAC;

④在更新事件(计数器溢出)时,会产生中断/DMA请求;

基本定时器框图

①时钟源

定时器的核心是计数器。要实现计数功能,首先要给它一个时钟源。基本定时器的时钟挂载在APB1总线,所以它的时钟来自于APB1总线,但是基本定时器时钟并不是由APB1总线直接提供,而是先经过一个倍频器。

当APB1的预分频器系数为1时,这个倍频器系数为1,即定时器的时钟频率等于APB1总线时钟频率;当APB1的预分频器系数≥2分频时,这个倍频器系数就为2,即定时器的时钟频率等于APB1总线时钟频率的两倍。

利用sys_stm32_clock_init()函数可以设置APB1总线时钟频率,APB1总线的预分频器分频系数。

例如,设置APB1总线时钟频率为42Mhz,APB1总线的预分频器分频系数是2,则挂载在APB1总线的定时器时钟频率为84Mhz。

②控制器

控制器除了控制定时器复位、使能、计数等功能之外,还可以用于触发DAC转换。

③时基单元

时基单元包括:计数器寄存器(TIMx_CNT)、预分频器寄存器(TIMx_PSC)、自动重载寄存器(TIMx_ARR) 。基本定时器的这三个寄存器都是16位有效数字,即可设置值范围是0~65535。

时基单元中的预分频器PSC,它有一个输入和一个输出。输入CK_PSC来源于控制器部分,实际上就是来自于内部时钟(CK_INT)。输出CK_CNT是分频后的时钟,它是计数器实际的计数时钟通过设置预分频器寄存器(TIMx_PSC)的值可以得到不同频率CK_CNT,计算为公式为:

f_CK_CNT= f_CK_PSC / (PSC[15:0]+1) 

上式中,PSC[15:0]是写入预分频器寄存器(TIMx_PSC)的值。

另外:预分频器寄存器(TIMx_PSC)可以在运行过程中修改它的数值,新的预分频数值将在下一个更新事件时起作用。因为更新事件发生时,会把TIMx_PSC寄存器值更新到其影子寄存器中,这才会起作用。

什么是影子寄存器?

从框图上看,可以看到预分频器PSC后面有一个影子,自动重载寄存器也有个影子,这就表示这些寄存器有影子寄存器。影子寄存器是一个实际起作用的寄存器,不可直接访问。举个例子:我们可以把预分频系数写入预分频器寄存器(TIMx_PSC),但是预分频器寄存器只是起到缓存数据的作用,只有等到更新事件发生时,预分频器寄存器的值才会被自动写入其影子寄存器中,这时才真正起作用。

自动重载寄存器及其影子寄存器的作用和上述同理。不同点在于自动重载寄存器是否具有缓冲作用还受到ARPE位的控制,当该位置0时,ARR寄存器不进行缓冲,我们写入新的ARR值时,该值会马上被写入ARR影子寄存器中,从而直接生效;当该位置1时,ARR寄存器进行缓冲,我们写入新的ARR值时,该值不会马上被写入ARR影子寄存器中,而是要等到更新事件发生才会被写入ARR影子寄存器,这时才生效。预分频器寄存器则没有这样相关的控制位,这就是它们不同点。

值得注意的是,更新事件的产生有两种情况,一是由软件产生,将TIMx_EGR寄存器的位UG置1,产生更新事件后,硬件会自动将UG位清零。二是由硬件产生,满足以下条件即可:计数器的值等于自动重装载寄存器影子寄存器的值。

更新事件和定时器上溢

基本定时器的计数器(CNT)是一个递增的计数器,当寄存器(TIMx_CR1)的CEN位置1,也就是使能定时器后,每来一个CK_CNT脉冲,TIMx_CNT的值就会递增加1。当TIMx_CNT值与 TIMx_ARR的设定值相等时,TIMx_CNT的值就会被自动清零并且会生成更新事件(如果开启相应的功能,就会产生 DMA请求、产生中断信号或者触发 DAC 同步电路),然后下一个CK_CNT脉冲到来,TIMx_CNT的值就会递增加1,如此循环。在此过程中,TIMx_CNT等于TIMx_ARR时,我们称之为定时器溢出,因为是递增计数,故而又称为定时器上溢。定时器溢出就伴随着更新事件的发生。

由上述可知,我们只要设置预分频寄存器和自动重载寄存器的值就可以控制定时器更新事件发生的时间。自动重载寄存器(TIMx_ARR)是用于存放一个与计数器作比较的值,当计数器的值等于自动重载寄存器的值时就会生成更新事件,硬件自动置位相关更新事件的标志位,例如:更新中断标志位。

下面举个例子来学习如何设置预分频寄存器和自动重载寄存器的值来得到我们想要的定时器上溢事件发生的时间周期。比如我们需要一个500ms周期的定时器更新中断,一般思路是先设置预分频寄存器,然后才是自动重载寄存器。假如我们设置的CK_INT为84MHz,我们把预分频系数设置为8400,即写入预分频寄存器的值为8399,那么fCK_CNT=84MHz/8400=10KHz。这样就得到计数器的计数频率为10KHz,即计数器1秒钟可以计10000个数。我们需要500ms的中断周期,所以我们让计数器计数5000个数就能满足要求,即需要设置自动重载寄存器的值为4999,另外还要把定时器更新中断使能位UIE置1,CEN位也要置1。

定时器计数模式和溢出条件

定时器溢出时间和计算方法

2、相关HAL库函数

HAL_TIM_Base_Init() 函数

HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim);

函数描述

 该函数用于初始化定时器。

函数形参

形参 1(TIM_HandleTypeDef *htim) 是 TIM_HandleTypeDef 结构体类型指针变量(亦称定时器句柄),其定义如下:

typedef struct

{

TIM_TypeDef                                                *Instance;                 /* 外设寄存器基地址 */

TIM_Base_InitTypeDef                                 Init;                           /* 定时器初始化结构体*/

HAL_TIM_ActiveChannel                             Channel;                  /* 定时器通道 */

DMA_HandleTypeDef                                   *hdma[7];                /* DMA 管理结构体 */

HAL_LockTypeDef                                        Lock;                       /* 锁定资源 */

__IO HAL_TIM_StateTypeDef                      State;                      /* 定时器状态 */

__IO HAL_TIM_ChannelStateTypeDef        ChannelState;         /* 定时器通道状态 */

__IO HAL_TIM_ChannelStateTypeDef        ChannelNState;      /* 定时器互补通道状态 */

__IO HAL_TIM_DMABurstStateTypeDef     DMABurstState;      /* DMA 溢出状态 */ }TIM_HandleTypeDef;

1)Instance:指向定时器寄存器基地址。

2)Init:定时器初始化结构体,用于配置定时器的相关参数。

3)Channel:定时器的通道选择,基本定时器没有该功能。

4)hdma[7]:用于配置定时器的 DMA 请求。

5)Lock:ADC 锁资源。

6)State:定时器工作状态。

7)ChannelState/ChannelNState:定时器通道/互补通道工作状态。

8)DMABurstState:DMA 溢出状态。

TIM_Base_InitTypeDef 这个结构体类型定义如下:

typedef struct

{

uint32_t    Prescaler;                                /* 预分频系数 */

uint32_t    CounterMode;                         /* 计数模式 */

uint32_t    Period;                                    /* 自动重载值 ARR */

uint32_t    ClockDivision;                         /* 时钟分频因子 */

uint32_t    RepetitionCounter;                 /* 重复计数器 */

uint32_t    AutoReloadPreload;              /* 自动重载预装载使能 */

} TIM_Base_InitTypeDef;

1)Prescaler:预分频系数,即写入预分频寄存器的值,范围 0 到 65535。

2)CounterMode:计数器计数模式,这里基本定时器只能向上计数。

3)Period:自动重载值,即写入自动重载寄存器的值,范围 0 到 65535。

4)ClockDivision:时钟分频因子,也就是定时器时钟频率 CK_INT 与数字滤波器所使用的采样 时钟之间的分频比,基本定时器没有此功能。

5)RepetitionCounter:设置重复计数器寄存器的值,用在高级定时器中。

6)AutoReloadPreload:自动重载预装载使能,即控制寄存器 1 (TIMx_CR1)的 ARPE 位。

函数返回值

 HAL_StatusTypeDef 枚举类型的值。

HAL_TIM_Base_Start_IT() 函数

HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);

函数描述

 该函数通过调用__HAL_TIM_ENABLE_IT 和__HAL_TIM_ENABLE 两个函数宏定义,实现更新定时器中断和使能定时器的功能。 

函数形参

形参 1(TIM_HandleTypeDef *htim) 是 TIM_HandleTypeDef 结构体类型指针变量,即定时器句柄。

函数返回值

 HAL_StatusTypeDef 枚举类型的值。

3、总结

STM32F407 的两个基本定时器(TIM6 和 TIM7),是最基本的计时器,主要用于计时。

  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值