Skip to main content
u23
Associate III
July 18, 2014
Question

Configure the timers count at 32-bit

  • July 18, 2014
  • 7 replies
  • 1257 views
Posted on July 18, 2014 at 08:39

Hi,

I'm using the device STM32F030C8T6 that has all the timers count at 16-bit.

I need using the timer count at 32-bit.

In the data sheet in the page 67 reads ''Maximum possible count with 32-bit counter''.

How can I configure the timer to count up to 32-bit?

Thanks
    This topic has been closed for replies.

    7 replies

    Tesla DeLorean
    Guru
    July 18, 2014
    Posted on July 18, 2014 at 15:19

    Some STM32F0 parts have a 32-bit counter, the part you have chosen does not.

    You'd need to cascade at pair of 16-bit counters in master/slave mode

    This might be illustrative

    STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\TIM\Cascade_Synchro
    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    u23
    u23Author
    Associate III
    July 18, 2014
    Posted on July 18, 2014 at 16:22

    Ok, Thanks

    u23
    u23Author
    Associate III
    July 21, 2014
    Posted on July 21, 2014 at 09:44

    I have configurated the TIM2 and TIM3 in cascade mode:

    uint8_t TIMER_ConfigSynchInCascade( void )

    {

      TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

        TIM_OCInitTypeDef  TIM_OCInitStructure;

     

        /* TIM2 and TIM3 clock enable */

        // --------------------------------------------------------------------------

        RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE);

        

        /* Time base configuration */

        // --------------------------------------------------------------------------

      TIM_TimeBaseStructure.TIM_Period = 65535;

      TIM_TimeBaseStructure.TIM_Prescaler = 15;

      TIM_TimeBaseStructure.TIM_ClockDivision = 0;

      TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

      TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

      TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

      /* Select the Master Slave Mode */

      TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

      /* Master Mode selection */

      TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);

      /* Slave Mode selection: TIM3 */

      TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated);

      TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1);

      /* TIM enable counter */

      TIM_Cmd(TIM3, ENABLE);

      TIM_Cmd(TIM2, ENABLE);

        return 0;

    }

    I

    n the main function

    , the LED4

    is

    turned on and off

    in the following mode:

    static __IO uint8_t Debug = 0;

    #define LEDToggleValue ((uint32_t) 100000)

    static __IO uint32_t CounterTimers = 0;

    int main(void)

    {

       /* Initialize Leds mounted on STM3210X-EVAL board */

      STM_EVAL_LEDInit(LED4);

      // Configura i timers in cascata

      TIMER_ConfigSynchInCascade();

      while (1)

      {

                // Toggle led

                CounterTimers = TIMER_GetCounter(TIM2)+TIMER_GetCounter(TIM3);

                if (  CounterTimers > LEDToggleValue )

                    STM_EVAL_LEDOn(LED4);

                else    

                    STM_EVAL_LEDOff(LED4);

        }

    }

    The LED4 is ever off!

    I have

    done something wrong

    in the configuration

    ?

    Thanks

    maxime
    Associate II
    July 21, 2014
    Posted on July 21, 2014 at 16:11

    Hi, 

    Not sure but I think you should use :

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE); instead of RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE);

    Tesla DeLorean
    Guru
    July 21, 2014
    Posted on July 21, 2014 at 17:34

    CounterTimers = TIMER_GetCounter(TIM2)+TIMER_GetCounter(TIM3);

    Does these functions deal with shifting the 16-bit word suitably?
    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    u23
    u23Author
    Associate III
    July 22, 2014
    Posted on July 22, 2014 at 08:45

    I have corrected the errors, but the timer TIM3 not counter!

    The TIMER_GetCounter(TIM2) function return the value in the range [0÷65535], but the TIMER_GetCounter(TIM3) function return zero.

    u23
    u23Author
    Associate III
    July 24, 2014
    Posted on July 24, 2014 at 08:38

    The solution is descript below:

    uint8_t TIMER_ConfigSynchInCascade( void )

    {

        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

        uint16_t PrescalerValue_RPM = 0;

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16 | RCC_APB2Periph_TIM17, ENABLE);

       /* Timer frequency configuration at 12 MHz */

        PrescalerValue_RPM = (uint16_t) (SystemCoreClock  / 12000000) - 1;

        

      /* Time base configuration */

      TIM_TimeBaseStructure.TIM_Period = 65535;

      TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue_RPM;

      TIM_TimeBaseStructure.TIM_ClockDivision = 0;

      TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

      TIM_TimeBaseInit(TIM16, &TIM_TimeBaseStructure);

      TIM_TimeBaseInit(TIM17, &TIM_TimeBaseStructure);

      /* Select the Master Slave Mode */

      TIM_SelectMasterSlaveMode(TIM16, TIM_MasterSlaveMode_Enable);

      /* Master Mode selection */

      TIM_SelectOutputTrigger(TIM16, TIM_TRGOSource_Update);

      /* Slave Mode selection: TIM17 */

      TIM_SelectSlaveMode(TIM17, TIM_SlaveMode_Gated);

      TIM_SelectInputTrigger(TIM17, TIM_TS_ITR1);

      /* Select the Master Slave Mode */

      TIM_SelectMasterSlaveMode(TIM17, TIM_MasterSlaveMode_Enable);

      /* Master Mode selection: TIM17 */

      TIM_SelectOutputTrigger(TIM17, TIM_TRGOSource_Update);

     

      /* TIM enable counter */

      TIM_Cmd(TIM17, ENABLE);

      TIM_Cmd(TIM16, ENABLE);

        

        return 0;

    }

    The function that return the counter value at 32-bit is:

    uint32_t GetCounter32Bit ( void )

    {

        uint16_t a, b, c, d;

        /* Reading twice to avoid overflow in the middle of reading */

        a = TIM16->CNT;

        b = TIM17->CNT;

        c = TIM16->CNT;

        d = TIM17->CNT;

        if((a != c) || (b != d))

            return ((uint32_t)c << 16) | d;

        else

            return ((uint32_t)a << 16) | b;

    }    

    I

    hope this is

    clear

    !