Skip to main content
joe239955_stm1_st
Associate
November 8, 2012
Question

Advanced-control timers (TIM1&TIM8) Center-aligned mode (up/down counting)

  • November 8, 2012
  • 3 replies
  • 1561 views
Posted on November 08, 2012 at 15:23

Evaluating the STM32F207 for a project.

I need to create a triangle waveform, starting from an arbitrary point between two limits, and it needs to be able to start in both incrementing or decrementing fashion. I intend to use DMA to play this waveform out to a DAC

I am looking at Advanced-control timers (TIM1&TIM8) Center-aligned mode (up/down counting), I understand that this only works between 0 and TIMx_ARR but I can offset the waveform to the correct point

From the manual page 297 I understand that

“In center-aligned mode, the counter counts from 0 to the auto-reload value (content of the TIMx_ARR register) – 1�

and that

“In this mode, the DIR direction bit in the TIMx_CR1 register cannot be written. It is updated

by hardware and gives the current direction of the counter.�

This indicates to me that when the mode is set the Counter register (TIMx_CNT) is cleared and the DIR direction bit is set to increment.

Question

1>Can the Counter register (TIMx_CNT) be loaded to an arbitrary value after the mode is set if the waveform needs to increment

2>If the waveform needs to start decrementing, could the TIMx_ARR register be set to a small value the timer run until the the limit is hit (now in the right state). Timer disabled (Bit 0 CEN: Counter enable). Then the TIMx_ARR and the Counter register (TIMx_CNT) register set to the proper value, and then reenabled

Thanks in advance

Joe

From the manual

******************************************

Advanced-control timers (TIM1&TIM8)

Page 297

Center-aligned mode (up/down counting)

In center-aligned mode, the counter counts from 0 to the auto-reload value (content of the

TIMx_ARR register) – 1, generates a counter overflow event, then counts from the autoreload

value down to 1 and generates a counter underflow event. Then it restarts counting

from 0.

In this mode, the DIR direction bit in the TIMx_CR1 register cannot be written. It is updated

by hardware and gives the current direction of the counter.

Page 329

Bits 6:5 CMS[1:0]: Center-aligned mode selection

….

….

11: Center-aligned mode 3. The counter counts up and down alternatively. Output compare

interrupt flags of channels configured in output (CCxS=00 in TIMx_CCMRx register) are set

both when the counter is counting up or down.

Note: It is not allowed to switch from edge-aligned mode to center-aligned mode as long as

the counter is enabled (CEN=1)

Bit 4 DIR: Direction

0: Counter used as upcounter

1: Counter used as downcounter

Note: This bit is read only when the timer is configured in Center-aligned mode or Encoder

mode.

******************************************

    This topic has been closed for replies.

    3 replies

    waclawek.jan
    Super User
    November 8, 2012
    Posted on November 08, 2012 at 20:52

    While the manual is not crystal clear in this matter, I'd say that the timer would start from the value you write to it and count in the direction you set in the DIR bit just before setting the up/down counting mode. In other words, I don't believe that setting the mode would affect/clear the TIMx_CNT register and the DIR bit; and I believe that the description is meant to say ''if the counter is in its reset state and then the up/down mode is enabled, it will count from 0 up and then down''.

    But why don't you just try it with a simple program?

    JW

    waclawek.jan
    Super User
    November 9, 2012
    Posted on November 09, 2012 at 14:20

    OK I tried and yes, it works exactly as I expected - after setting DIR and TIMx_CNT, setting the up/down mode and enabling the timer does not clear DIR/TIMx_CNT, but it starts off where they were set.

    JW

    #include ''stm32f4xx.h''

    #define AND &

    #define OR  |

    extern volatile uint32_t a;

    volatile uint32_t a;

    int main(void) {

      // default HSI clock = 16MHz

      RCC->CFGR |= 0

        OR  RCC_CFGR_HPRE_DIV1    // AHB prescaler set to 1 -> AHB clock = 16MHz

        OR  RCC_CFGR_PPRE1_DIV4   // APB1 prescaler set to 4 -> APB1 clock = 4MHz (required to be < 42MHz)

        OR  RCC_CFGR_PPRE2_DIV2   // APB2 prescaler set to 2 -> APB2 clock = 8MHz (required to be < 84MHz)

      ;

      RCC->AHB1ENR |= 0           // enable clock to all IOs

        OR  RCC_AHB1ENR_GPIOAEN

        OR  RCC_AHB1ENR_GPIOAEN

        OR  RCC_AHB1ENR_GPIOBEN

        OR  RCC_AHB1ENR_GPIOCEN

        OR  RCC_AHB1ENR_GPIODEN

        OR  RCC_AHB1ENR_GPIOEEN

        OR  RCC_AHB1ENR_GPIOFEN

        OR  RCC_AHB1ENR_GPIOGEN

        OR  RCC_AHB1ENR_GPIOHEN

        OR  RCC_AHB1ENR_GPIOIEN

      ;

      RCC->APB2ENR |= RCC_APB2ENR_TIM8EN;          // enable clock to timer

      RCC->APB2RSTR |= RCC_APB2RSTR_TIM8RST;       // pulse to reset timer

      RCC->APB2RSTR &= ~RCC_APB2RSTR_TIM8RST;

      // set PA0 to alternative, select for TIM8_ETR

      GPIOA->MODER |= 0

        OR (GPIO_Mode_AlternateFunction * GPIO_MODER_MODER0_0)

      ;

      GPIOA->AFR[0] |= 0

        OR (GPIO_AlternateFunction_TIM8 * GPIO_AFRL_AFRL0_0)

      ;

      // set clock input to ETR, external clock source mode 2 - no prescaler, but apply the heaviest filter in futile attempt to reduce the bouncing somewhat :)

      TIM8->SMCR = 0

        OR ( 0b1111 * TIM_SMCR_ETF_0 )

        OR ( 1      * TIM_SMCR_ECE   )

      ;

      // set reload value to some ''normal'' value so we can ''see'' how it's working through the debugger

      TIM8->ARR = 20;

      // set counter somewhere in the middle

      TIM8->CNT = 10;

      // set DIR to where we want it to go at start, CMS[1:0] as up/down, mode is toggle, and enable the timer

      TIM8->CR1 |= 0

        OR (0b11 * TIM_CR1_CMS)

        OR (1    * TIM_CR1_DIR)  // 0 - count up; 1 - count down

        OR (1    * TIM_CR1_CEN)

      ;

      // and an infinite loop to observe the behaviour in the simulator

      while(1) {

        a = TIM8->CNT;

      };

    }

    joe239955_stm1_st
    Associate
    November 13, 2012
    Posted on November 13, 2012 at 16:00

    Thank you very much for the input.

    The fact that they can be controlled before setting th up/dwn mode will make life much easier.

    I will pass this on to my embedded guy

    Thanks

    Joe