STM32 TIM1高级定时器RCR重复计数器的理解

时间:2024-02-20 11:06:04

STM32 TIM1高级定时器RCR重复计数器的理解

TIMx_RCR重复计数器寄存器,重复计数器只支持高级定时器TIM1TIM8,下面看标准外设库的TIM结构体的封装;

typedef struct
{
  uint16_t TIM_Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.
                                       This parameter can be a number between 0x0000 and 0xFFFF */

  uint16_t TIM_CounterMode;       /*!< Specifies the counter mode.
                                       This parameter can be a value of @ref TIM_Counter_Mode */

  uint16_t TIM_Period;            /*!< Specifies the period value to be loaded into the active
                                       Auto-Reload Register at the next update event.
                                       This parameter must be a number between 0x0000 and 0xFFFF.  */ 

  uint16_t TIM_ClockDivision;     /*!< Specifies the clock division.
                                      This parameter can be a value of @ref TIM_Clock_Division_CKD */

  uint8_t TIM_RepetitionCounter;  /*!< Specifies the repetition counter value. Each time the RCR downcounter
                                       reaches zero, an update event is generated and counting restarts
                                       from the RCR value (N).
                                       This means in PWM mode that (N+1) corresponds to:
                                          - the number of PWM periods in edge-aligned mode
                                          - the number of half PWM period in center-aligned mode
                                       This parameter must be a number between 0x00 and 0xFF. 
                                       @note This parameter is valid only for TIM1 and TIM8. */
} TIM_TimeBaseInitTypeDef;       

可以看到uint8_t TIM_RepetitionCounter将暂存RCR寄存器的值,从后面注释可以得知;
RCR寄存器中的值会递减到0,在允许更新事件UEV发生的情况下,则TIM的更新事件UEV就会产生;
如果设置RCR的值为N,那么PWM模式下,更新事件将会在弟N+1个周期发生;
下面根据PWM模式加以区分;

  • 边沿模式edge-aligned mode,延迟PWM周期数量和N相同;
  • *对齐模式center-aligned mode,延迟PWM周期数量等于N2\cfrac{N}{2}

更新事件UEV会在当计数器达到溢出条件(向下计数时的下溢条件)并当TIMx_CR1寄存器中的UDIS位等于0时产生

下面看STM32参考手册中的一张图;
在这里插入图片描述
从图中不难发现;
*对齐模式下:

  • RCR = 0,更新事件没有延迟;
  • RCR = 1,更新事件延后了半个PWM周期;
  • RCR = 2, 更新事件延后了一个PWM周期;
  • RCR = 3,更新事件延后了cfrac32cfrac{3}{2}个PWM周期;
    因此,*对齐模式center-aligned mode,更新事件延迟的PWM周期数量等于RCR2\cfrac{RCR}{2}

RCR 寄存器的范围是 0~0xFF;

边沿对齐模式下:

  • RCR = 0,更新事件没有延迟;
  • RCR = 1,更新事件延后了一个PWM周期;
  • RCR = 2, 更新事件延后了两个PWM周期;
  • RCR = 3,更新事件延后了三个PWM周期;
    因此,边沿对齐模式延迟的PWM周期数量等于RCRRCR

这么一来,TIM中的UEV的使用就变得非常灵活。
实际的应用中,对于STM32芯片的ADC的转换启动,一般分为软件启动或外部触发事件启动。其中外部触发事件启动,可以是定时器触发事件或EXTI引脚信号。在很多应用场合,比如电机、电源、变频器等应用中,ADC的采样点可能会有很严格的时间要求,如果采样点选择错误,可能会给整个控制系统造成严重不良后果。这里针对STM32的定时器周期性地触发ADC采样的实现方式做个简要介绍。
这里以STM32F1的TIMER1 触发ADC注入通道的转换为例【当然,规则通道也可以使用定时器触发】。我们可以利用定时器更新事件或比较输出信号作为ADC的触发使能信号。根据STM32F1参考手册查表得知,可以使用TIM1的TRGO事件或通道CH4的捕捉事件来触发注入通道的ADC转换。

1、使用TIM1 TRGO来触发ADC

// 选择Tim1更新事件作为TRGO

TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_Update);

//设定T1_TRGO作为ADC触发源

ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_T1_TRGO;

特别提醒:经常有人忘记配置上面红色语句,那就相当于使用了默认的TRGO信号。但对于一个定时器来讲,可以作为TRGO的信号很多,有时默认的并非你要的信号。

在这里插入图片描述

2、利用TIM1 CH4的比较事件来触发ADC

这里就是选择OC4REF信号作为TRGO输出来触发ADC.

// 选择OC4REF作为TRGO;

TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_OC4Ref);

//设定T1_TRGO作为ADC触发源

ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_T1_TRGO;

相比上面第一种方法,ADC采样时间点更为灵活可调,不仅仅局限于定时器的更新事件。

            图一:间隔触发ADC采样点

有时候,我们可能需要多个周期才需进行一次AD触发采样及相关计算。如果时间是基于更新时刻又是定时周期的倍数,较为方便的办法就是使用定时器里的重复计数器,使用更新事件作为TRGO。软件设置就是在上面第一种方法的基础上增加一句对重复计数器TIMx_RCR的设置。图一的蓝色箭头即为此种情况的触发点设定。基本配置如下:

//配置重复计数器为2次

TIM_TimeBaseStructure.TIM_RepetitionCounter = 1;

// 选择Tim1更新事件作为TRGO

TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_Update);

//设定T1_TRGO作为ADC触发源

ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_T1_TRGO;

在这里插入图片描述

如果要实现跨周期非更新时间点采样和计算,即上图中绿色箭头所指的情形。我们可以考虑使用多次采样配合中断进行计数的方式或者引入其它定时器进行分频后来灵活处理。